常用设计模式之代理(动态代理)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用设计模式之代理(动态代理)相关的知识,希望对你有一定的参考价值。
常用设计模式之代理(动态代理)
-
UML
-
Code1
1 interface Subject{void doSth();} 2 class RealSubject implements Subject{ 3 public void doSth(){ 4 System.out.println("RealSubject doSth...."); 5 } 6 } 7 class ProxyHandler implements InvocationHandler 8 { 9 private Object obj; 10 public ProxyHandler(Object obj){ this.obj = obj; } 11 //private Subject subject; 12 //public ProxyHandler(Subject subject){this.subject = subject;} 13 public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException 14 { 15 System.out.println(proxy.getClass().getName()); 16 System.out.println("before -----------"); 17 Object result = method.invoke(this.obj, args); 18 System.out.println("after -----------"); 19 return result; 20 } 21 } 22 public class Test{ 23 public static void main(String[] args){ 24 Subject proxy = (Subject)Proxy.newProxyInstance( 25 Subject.class.getClassLoader(), 26 new Class[]{ Subject.class }, 27 new ProxyHandler(new RealSubject())); 28 proxy.doSth(); 29 System.out.println(proxy.getClass().getName()); 30 } 31 } 32 /*out: 33 com.wrb.$Proxy0 34 before ----------- 35 RealSubject doSth.... 36 after ----------- 37 com.wrb.$Proxy0 38 */
-
Code2
1 interface UserService { 2 void add(); 3 } 4 class UserServiceImpl implements UserService { 5 public void add() { 6 System.out.println("add"); 7 } 8 } 9 /** 10 * 实现自己的InvocationHandler 11 */ 12 class MyInvocationHandler implements InvocationHandler { 13 14 // 目标对象 15 private Object target; 16 17 /** 18 * 构造方法 19 * @param target 目标对象 20 */ 21 public MyInvocationHandler(Object target) { 22 super(); 23 this.target = target; 24 } 25 26 /** 27 * 执行目标对象的方法 28 */ 29 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 30 System.out.println("before------------------"); 31 32 Object result = method.invoke(target, args); 33 34 System.out.println("after------------------"); 35 return result; 36 } 37 38 /** 39 * 获取目标对象的代理对象 40 * @return代理对象 41 */ 42 public Object getProxy() { 43 return Proxy.newProxyInstance( 44 Thread.currentThread().getContextClassLoader(), 45 target.getClass().getInterfaces(), 46 this); 47 } 48 } 49 public class Test{ 50 public static void main(String[] args){ 51 MyInvocationHandler handler = 52 new MyInvocationHandler(new UserServiceImpl()); 53 UserService proxy = (UserService) handler.getProxy(); 54 proxy.add(); 55 } 56 } 57 /*out: 58 before------------------ 59 add 60 after------------------ 61 */
-
实现原理
Proxy.newProxyInstance() 返回的代理对象subjectProxy(全都继承了父类Proxy)实现了其第二个参数中的全部接口,且包含了其第三个参数中的处理器对象handler。无论调用subjectProxy的哪个方法,实际都被转为调用处理器对象的invoke()方法。
(
class SubjectProxy extends Proxy implements Asubject, Bsubject, Csubject{
private InvocationHandler myHandler;
public **( * ) {
subjectProxy.myHandler.invoke(this, method, args);
}
}
)
因为subjectProxy已经继承了父类Proxy,加上java单继承,因此此法只能实现接口的动态代理,无法实现类的动态代理。想实现类的动态代理,可以使用CGLIB(Code Generation Library)。(目前为止已接触三种代理的实现:装饰者模式实现的代理(decorator),JDK 动态代理(dynamic proxy) 和 Cglib 动态代理 (cglib proxy))。
参考:
JDK1.8 源码,
http://blog.csdn.net/jiankunking/article/details/52143504
http://rejoy.iteye.com/blog/1627405
http://www.360doc.com/content/14/0801/14/1073512_398598312.shtml
以上是关于常用设计模式之代理(动态代理)的主要内容,如果未能解决你的问题,请参考以下文章