用Java动态代理实现委托模式- - JavaEye技术网站

????? 委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。委托模式是一项基本技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。委托模式使得我们可以用聚合来替代继承,它还使我们可以模拟mixin。
“委托”在C#中是一个语言级特性,而在Java语言中没有直接的对应,但是我们可以通过动态代理来实现委托!代码如下:

  1. import?java.lang.reflect.InvocationHandler; ??
  2. import?java.lang.reflect.Method; ??
  3. import?java.lang.reflect.Proxy; ??
  4. /* ?
  5. ?*?@author?Liusheng ?
  6. ?*?实现“委托”模式,用户需要实现InvocationHandler接口; ?
  7. ?*?参考:http://www.uml.org.cn/j2ee/200411036.htm ?
  8. ?*/??
  9. public?abstract?class?Delegator?implements?InvocationHandler?{ ??
  10. ????//RelegateTo针对每个对象都要生成一个实例,因而非Static的log,代价比较高。 ??
  11. ????//protected?Log?_log?=?LogFactory.getLog(this.getClass());?? ??
  12. ????//private?static?Log?_log?=?LogFactory.getLog(RelegateTo.class); ??
  13. ????//-------------------------------------------- ??
  14. ????protected?Object?obj_orgin?=?null;??//原始对象 ??
  15. ????protected?Object?obj_proxy?=?null;??//代理对象 ??
  16. ????//-------------------------------------------- ??
  17. ????public?Delegator()??{ ??
  18. ????????//空 ??
  19. ????} ??
  20. ????public?Delegator(Object?orgin){ ??
  21. ????????this.createProxy(orgin); ??
  22. ????} ??
  23. ????//-------------------------------------------- ??
  24. ????protected?Object?createProxy(Object?orgin)?{ ??
  25. ????????obj_orgin?=?orgin; ??
  26. ????????obj_proxy?=?Proxy.newProxyInstance( ??
  27. ????????????????orgin.getClass().getClassLoader(),??//加载器 ??
  28. ????????????????orgin.getClass().getInterfaces(),???//接口集 ??
  29. ????????????????this);??//委托 ??
  30. ????????//_log.debug("#?委托代理:"+obj_proxy); ??
  31. ????????return?obj_proxy; ??
  32. ????}??? ??
  33. ????protected?Object?invokeSuper(Method?method,?Object[]?args) ??
  34. ????throws?Throwable?{ ??
  35. ????????return?method.invoke(obj_orgin,?args);?? ??
  36. ????} ??
  37. ????//--------------实现InvocationHandler接口,要求覆盖------------ ??
  38. ????public?Object?invoke(Object?obj,?Method?method,?Object[]?args) ??
  39. ????throws?Throwable?{ ??
  40. ????????//?缺省实现:委托给obj_orgin完成对应的操作 ??
  41. ????????if?(method.getName().equals("toString"))?{??//对其做额外处理 ??
  42. ????????????return?this.invokeSuper(method,?args)+"$Proxy"; ??
  43. ????????}else?{?????//注意,调用原始对象的方法,而不是代理的(obj==obj_proxy) ??
  44. ????????????return?this.invokeSuper(method,?args); ??
  45. ????????} ??
  46. ????} ??
  47. }??


下面的代码,则是作为一个委托的例子,实现Map的功能。

  1. import?java.io.IOException; ??
  2. import?java.lang.reflect.Method; ??
  3. import?java.util.Hashtable; ??
  4. import?java.util.Map; ??
  5. import?org.apache.commons.logging.Log; ??
  6. import?org.apache.commons.logging.LogFactory; ??
  7. import?com.bs2.core.UtilLog; ??
  8. /** ?
  9. ?*?@author?Liusheng ?
  10. ?*?本代码主要用于演示RelegateTo的使用方法 ?
  11. ?*/??
  12. public?class?Delegator4Map?extends?Delegator?{ ??
  13. ????private?static?Log?_log?=?LogFactory.getLog(Delegator4Map.class); ??
  14. ????private?Map?orginClass?=?null;??//原始对象 ??
  15. ????private?Map?proxyClass?=?null;??//代理对象 ??
  16. ???? ??
  17. ????public?Map?getOrgin()?{?return?orginClass;??} ??
  18. ????public?Map?getProxy()?{?return?proxyClass;??} ??
  19. ???? ??
  20. ????public?Delegator4Map(Map?orgin)?{ ??
  21. ????????super(orgin); ??
  22. ????????orginClass?=?orgin; ??
  23. ????????proxyClass?=?(Map)super.obj_proxy; ??
  24. ????} ??
  25. ????public?Object?invoke(Object?obj,?Method?method,?Object[]?args) ??
  26. ????throws?Throwable?{ ??
  27. ????????if?(method.getName().equals("size"))?{??//修改close处理逻辑 ??
  28. ????????????_log.debug("原始?size()="+super.invoke(obj,?method,?args)); ??
  29. ????????????Object?res2?=?new?Integer(-1); ??
  30. ????????????_log.debug("修改?size()="+res2); ??
  31. ????????????return?res2; ??
  32. ????????}else?{ ??
  33. ????????????return?super.invoke(obj,?method,?args); ??
  34. ????????} ??
  35. ????}??? ??
  36. ????public?static?void?main(String[]?args)?throws?IOException?{ ??
  37. ????????UtilLog.configureClassPath("resources/log4j.properties",?false); ??
  38. ????????Delegator4Map?rtm?=?new?Delegator4Map(new?Hashtable()); ??
  39. ????????Map?m?=?rtm.getProxy(); ??
  40. ????????m.size(); ??
  41. ????????_log.debug("代理:"+m.toString()); ??
  42. ????} ??
  43. }??


注意:UtilLog仅仅是用于配置log4j属性文件位置,如果log4j.properties就在缺省的运行路径下,则无需单独配置。或者用System.out输出来替代_log输出。

郑重声明:资讯 【用Java动态代理实现委托模式- - JavaEye技术网站】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——