java动态代理

代理有感:就是通过代理对象返回一个实例化的目标对象,然后当这个目标对象执行某方法时,先执行代理对象的默认的invoke()方法,再通过invoke执行需要的方法。

在文章代理模式之静态代理(2)中我们了解到静态代理的运行机制.同时在文章的尾部看到了静态代理的不足.而动态代理可以弥补那些不足,接下来我们将详细的来了解一下动态代理.

         JavaJava.lang.reflect包中提供Proxy类和InvocationHandler.我们可以通过他们两个生成动态的JDK动态代理类或者动态代理对象.

 

          一个类:Proxy(动态生成一个代理对象)必须这个类实现了接口才可以生成代理,如果没有接口的话就不能生成代理.它是通过接口在内存中建立一个类.

         一个接口:Interface InvocationHandler.系统生成的每个代理对象都有一个与之相对应的InvocationHandler对象.

 

 

具体代码示例:

        由于在上文中的接口类和目标类没有进行更改,这里不再赘述.需要更改的是将原来的静态代理中手动添加的代理类删除.取而代之的是一个实现InvocationHandler接口的LogHandler;

LogHandler:(在原有的基础之上添加日志功能)

 


[java]  view plain copy print ?
  1. import java.lang.reflect.InvocationHandler;  
  2. import java.lang.reflect.Method;  
  3. import java.lang.reflect.Proxy;  
  4. import java.text.SimpleDateFormat;  
  5.   
  6. public class LogHandler implements InvocationHandler {  
  7.       
  8.     //对目标对象生成代理对象,需要将目标对象传过来.可以使用构造方法和下面的方法  
  9.     private Object targetObject;  
  10.     public Object newProxyInstance(Object targetObject){  
  11.          this.targetObject=targetObject;  
  12.         //根据传来的对象动态生成代理  
  13.         //第一个参数是类加载器,需要和目标对象的类加载器一样.  
  14.         //第二个参数是目标类的所有接口.会根据接口创建出代理类,代理类具有目标类的所有方法,但是方法里没有任何东西.  
  15.         //第三个参数需要回调InvocationHandler中的invoke方法.也就是实现InvocationHandler的对象.  
  16.          return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);  
  17.               
  18.           
  19.     }  
  20.       
  21.     /** 
  22.      * method表示代理目标的方法,可以动态进行获取 
  23.      */  
  24.     public Object invoke(Object proxy, Method method, Object[] args)  
  25.             throws Throwable {  
  26.         //获得当前时间  
  27.          SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  28.          String datetime = tempDate.format(new java.util.Date());  
  29.            
  30.         //方法开始日志记录  
  31.         System.out.println("startTime: "+datetime+"   start-->>"+method.getName());  
  32.           
  33.         //方法的相关参数  
  34.         for(int i=0;i<args.length;i++){  
  35.             System.out.println(args[i]);  
  36.         }  
  37.           
  38.         //方法的返回值  
  39.         Object result=null;  
  40.         try{  
  41.               
  42.             //调用目标的方法  
  43.             result =method.invoke(targetObject, args);  
  44.               
  45.             //方法成功日志记录  
  46.             System.out.println("successTime: "+datetime+"   success-->>"+method.getName());  
  47.               
  48.         }catch(Exception e){  
  49.             e.printStackTrace();  
  50.               
  51.             //方法失败日志记录  
  52.             System.out.println("errorTime: "+datetime+"   error-->>"+method.getName());  
  53.             throw e;  
  54.         }  
  55.           
  56.         return result;  
  57.     }  
  58.   
  59. }  


客户端代码:

[java]  view plain copy print ?
  1. /** 
  2.  * 添加一个用户 
  3.  */  
  4. public class Client {  
  5.     public static void main(String[] args){  
  6.            
  7.         LogHandler logHandler=new LogHandler();  
  8.         UserManager userManager=(UserManager)logHandler.newProxyInstance(new UserManagerImpl());  
  9.         userManager.addUser("00001""刘德华");  
  10.     }  
  11. }  

 

执行结果如下:

startTime: 2012-08-10 16:49:37  start-->>addUser

00001

刘德华

UserManagerImpl.addUser()userId-->00001

successTime: 2012-08-10 16:49:37  success-->>addUser

 


    使用动态代理,我们可以看到非常好的解耦效果.当然,在我们使用Proxy的时候也不是随意的用的,通常都是为一个指定的目标对象来生成动态代理.这种动态代理在AOP(AspectOrient Program)面向切面编程中称之为AOP代理.AOP代理可以替代目标对象,并且包含目标对象的全部方法,同时在已有方法的基础之上向前,向后加入一些通用处理的方法,例如上例中的日志处理.

 

           通过对动态代理模式的研究和学习可以看到编程的艺术性,同时也在演绎着面向对象的核心思想

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值