按照代理类的创建时期,代理类可分为两种。
l 静态代理类:由程序员创建或由特定工具自动生成
源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
l 动态代理类:在程序运行时,运用反射机制动态创建而成。

可以看出静态代理类有一个很不爽的缺点:当如果接口加一个方法(把上面所有的代码的注释给去掉),所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度。动态代理就可以避免这个缺点。

3 。动态代理

动态代理与普通的代理相比较,最大的好处是接口中声明的所有方法都被转移到一个集中的方法中处理(invoke),这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。

动态代理只能代理接口代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用代理接口的所有方法时需要调用的,该invoke方法返回的值是代理接口的一个实现类

代码实例:
  1. package ttitfly.proxy;       
  2.       
  3. import java.lang.reflect.InvocationHandler;       
  4. import java.lang.reflect.Method;       
  5. import java.lang.reflect.Proxy;       
  6. //动态代理类只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类       
  7. public class DynamicProxy implements InvocationHandler{       
  8.            
  9.     private Object object;        
  10.     //绑定关系,也就是关联到哪个接口(与具体的实现类绑定)的哪些方法将被调用时,执行invoke方法。   
  11.     //Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时需要执行哪个InvocationHandler的invoke方法   
  12.     public Object bindRelation(Object object){        
  13.         this.object = object;       
  14.         return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);        
  15.     }        
  16.     //拦截关联的这个实现类的方法被调用时将被执行       
  17.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        
  18.         System.out.println("Welcome");       
  19.         Object result = method.invoke(object, args);        
  20.         return result;       
  21.     }       
  22.       
  23. }       


 

测试类:

java 代码
  1. package ttitfly.proxy;       
  2.       
  3. public class TestDynamicProxy {       
  4.     public static void main(String[] args){       
  5.         HelloWorld helloWorld = new HelloWorldImpl();       
  6.         DynamicProxy dp = new DynamicProxy();       
  7.         //在这里绑定的是HelloWorld,也就是HelloWorld是被代理接口。所以绑定关系时,需要传递一个HelloWorld的实现类的实例化对象。       
  8.         HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld);        
  9.         helloWorld1.print();        
  10.         helloWorld1.say();       
  11.            
  12.         //helloWorld2将不被拦截   
  13.         HelloWorld helloWorld2 = new HelloWorldImpl();   
  14.         helloWorld2.print();        
  15.         helloWorld2.say();   
  16.            
  17.     }       
  18. }       


------君临天下,舍我其谁------