设计模式 --代理模式--动态代理

动态代理


动态代理类图


               


代码示例



代理类(不明白,就看看注释吧)

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.liang.pattern;  
  2.   
  3. import java.lang.reflect.InvocationHandler;  
  4. import java.lang.reflect.Method;  
  5. import java.lang.reflect.Proxy;  
  6. /** 
  7.  * 采用JDK动态代理必须实现InvocationHandler接口,采用Proxy类创建相应的代理类 
  8.  * @author liang 
  9.  * 
  10.  */  
  11. public class ProxyHandler implements InvocationHandler {  
  12.   
  13.     private Object targetObject;  
  14.     /** 
  15.      * 目标的初始化方法,根据目标生成代理类 
  16.      * @param targetObject 
  17.      * @return 
  18.      */  
  19.     public Object newProxyInstance(Object targetObject){  
  20.         this.targetObject = targetObject;  
  21.         //第一个参数,目标的装载器  
  22.         //第二个参数,目标接口,为每个接口生成代理  
  23.         //第三个参数,调用实现了InvocationHandler的对象,当你一调用代理,代理就会调用InvocationHandler的invoke方法  
  24.         return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);  
  25.     }  
  26.       
  27.     /** 
  28.      * 反射,这样你可以在不知道具体的类的情况下,根据配置的参数去调用一个类的方法。在灵活编程的时候非常有用。 
  29.      */  
  30.     public Object invoke(Object proxy, Method method, Object[] args)  
  31.             throws Throwable {  
  32.         //记录日志等操作或打印输入参数  
  33.         System.out.println("start-->>" + method.getName());  
  34.         for(int i=0;i<args.length;i++){  
  35.             //打印调用目标方法的参数  
  36.             System.out.println(args[i]);  
  37.         }  
  38.         Object ret = null;  
  39.         try{  
  40.             //调用目标方法  
  41.             ret = method.invoke(targetObject, args);  
  42.             //执行成功,打印成功信息  
  43.             System.out.println("success-->>" + method.getName());  
  44.         }catch(Exception e){  
  45.             e.printStackTrace();  
  46.             //失败时,打印失败信息  
  47.             System.out.println("error-->>" + method.getName());  
  48.             throw e;  
  49.         }  
  50.           
  51.         return ret;  
  52.     }  
  53.   
  54. }  

客户端调用

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.liang.pattern;  
  2.   
  3. public class Client {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.   
  10.         ProxyHandler proxyHandler = new ProxyHandler();  
  11.         UserManager userManager = (UserManager)proxyHandler.newProxyInstance(new UserManagerImpl());  
  12.           
  13.         String name = userManager.findUser("0001");  
  14.         System.out.println("client.main-->>" + name);  
  15.     }  
  16.   
  17. }   


输出结果,运行成功

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. start-->>findUser  
  2. 0001  
  3. UserManagerImpl.findUser() userId-->>0001  
  4. success-->>findUser  
  5. client.main-->>于亮  


接口和目标类,同上,我就不再浪费大家的带宽了。


优缺点


优点

1、一个动态代理类更加简单了,可以解决创建多个静态代理的麻烦,避免不断的重复多余的代码

2、调用目标代码时,会在方法“运行时”动态的加入,决定你是什么类型,才调谁,灵活


缺点

1、系统灵活了,但是相比而言,效率降低了,比静态代理慢一点

2、动态代理比静态代理在代码的可读性上差了一点,不太容易理解

3、JDK动态代理只能对实现了接口的类进行代理


总结


       静态代理VS动态代理,打成了平手,各自有各的独特之处,均不可代替,在项目中到底使用哪种代理,没有最好,只有更合适。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值