设计模式之Dynamic Proxy-动态代理

动态代理(Dynamic Proxy)是JDK5 提供的一种新特性。其特点在于在程序的运行时刻动态的创建出代理类及其对象,而不像我们使用静态代理时必须在编译之前定义好代理类。在运行时刻,框架帮我们动态的创建出一个实现了多个接口的代理类,每个代理类的对象都会和一个InvocationHandler接口的实现类相关联。当我们调用了代理对象所代理的接口中的方法的时候,这个调用的信息会被传递给InvocationHandler的invoke方法。在 invoke方法的参数中可以获取到代理对象、方法对应的Method对象和调用的实际参数(内部是通过反射来实现的)。 invoke方法的返回值被返回给使用者,至于返回什么值可以由自己来定义,这种做法实际上相当于对方法调用进行了AOP拦截。

 
创建动态代理的步骤如下:
1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法。
2. 创建被代理类以及接口
3. 通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)创建一个代理
4. 通过代理来调用方法(此代理实现了被代理类的接口)

傻蛋写了个示例代码
?[Copy to clipboard] Download DynamicProxy.java
 
 
 
 
  1. /**  
  2.  * DynamicSubject.java  
  3.  * dynamicproxy  
  4.  *  
  5.  * Function: 动态代理类, java.lang.reflect.Proxy 是运行时生成的Class,在生成它的时候你必须传递  
  6.  * 一组Interfaces给它(多个接口),然后返回的对象就实现了这些接口,这个Proxy就是一个纯粹的Porxy,  
  7.  * 所以我们必须提供一个InvocationHandler,由它来接替  
  8.  *  
  9.  *   ver     date           author  
  10.  * ──────────────────────────────────  
  11.  *           2011-6-12      Leon  
  12.  *  
  13.  * Copyright (c) 2011, TNT All Rights Reserved.  
  14. */  
  15.    
  16. package dynamicproxy;  
  17.    
  18. import java.lang.reflect.InvocationHandler;  
  19. import java.lang.reflect.Method;  
  20. import java.lang.reflect.Proxy;  
  21.    
  22. /**  
  23.  * ClassName:DynamicSubject  
  24.  * Function: TODO ADD FUNCTION  
  25.  * 创建动态代理的步骤如下:  
  26.  * 1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法。  
  27.  * 2. 创建被代理类以及接口  
  28.  * 3. 通过Proxy的静态方法newProxyInstance(ClassLoader loader,  
  29.  *        Class[] interfaces, InvocationHandler h)创建一个代理  
  30.  * 4. 通过代理来调用方法(此代理实现了被代理类的接口)  
  31.  *  
  32.  *  
  33.  * Reason:   TODO ADD REASON  
  34.  *  
  35.  * @author   Leon  
  36.  * @version  
  37.  * @since    Ver 1.1  
  38.  * @Date     2011-6-12  
  39.  */  
  40. public class DynamicProxy implements InvocationHandler {  
  41.    
  42.     private Object sub ;   
  43.    
  44.     public Object getSub() {  
  45.         return sub;  
  46.     }  
  47.     public void setSub(Object sub) {  
  48.         this.sub = sub;  
  49.     }  
  50.     public DynamicProxy(Object obj){  
  51.         this.sub=obj;  
  52.     }  
  53.     //proxy是框架动态生成的代理类  
  54.     @Override  
  55.     public Object invoke(Object proxy, Method method, Object[] args)  
  56.             throws Throwable {  
  57.    
  58.         // TODO Auto-generated method stub  
  59.         Object result = null ;  
  60.         System.out.println("before calling: " +  method);  
  61.    
  62.         //此处是真正被代理的对象  
  63.         result=method.invoke(sub, args);  
  64.    
  65.         System.out.println("after calling ...");  
  66.    
  67.         return result;  
  68.     }  
  69.    
  70.     public static void main(String...  args){  
  71.    
  72.         RealSubject  realSubject = new RealSubject();  
  73.    
  74.         DynamicProxy dynamicProxy = new DynamicProxy(realSubject);  
  75.    
  76. //      InvocationHandler invocationHandler = dynamicProxy;  
  77.    
  78.         //动态生成一个代理对象,返回的对象既不是RealSubject实例也不是DynamicPorxy的实例,而是动态生成  
  79.         //的一个实例 $prxoy0,它实现了realSubject.getClass().getInterfaces()这些接口  
  80.         ISubject subject=(ISubject)Proxy.newProxyInstance(dynamicProxy.getClass().getClassLoader(),  
  81.                   realSubject.getClass().getInterfaces(),dynamicProxy);  
  82.    
  83.         //当调用这一句的时候,$proxy0就会调用上面传入的invocationHandler的invoke方法,所以上面的方法要传入invocationHandler。  
  84.         System.out.println("--------------------------Porxy realSubject1 ------------------------------------");  
  85.         subject.request();  
  86.         String result=subject.test();  
  87.         System.out.println("return by test method :" + result);  
  88.         System.out.println("--------------------------Proxy realSubject2--------------------------------------");  
  89.         dynamicProxy.setSub(new RealSubject2());  
  90.         subject.request();  
  91.    
  92.         System.out.println("proxy generate by system is :"+subject.getClass());  
  93.    
  94.     }  
  95.    
  96. }  
  97.    
  98. interface ISubject {  
  99.     public void request();  
  100.     public String test();  
  101. }  
  102.    
  103. class RealSubject implements ISubject {  
  104.    
  105.     @Override  
  106.     public void request() {  
  107.    
  108.         // TODO Auto-generated method stub  
  109.         System.out.println("From  real  subject...request method....");  
  110.     }  
  111.    
  112.     @Override  
  113.     public String test() {  
  114.    
  115.         // TODO Auto-generated method stub  
  116.         String str ="From real subject.....test  method.....";  
  117.         return  str ;   
  118.    
  119.     }  
  120. }  
  121.    
  122. class RealSubject2 implements ISubject {  
  123.    
  124.     @Override  
  125.     public void request() {  
  126.    
  127.         // TODO Auto-generated method stub  
  128.         System.out.println("From  real  subject2...request method....");  
  129.     }  
  130.    
  131.     @Override  
  132.     public String test() {  
  133.    
  134.         // TODO Auto-generated method stub  
  135.         System.out.println("From real subject2 .....test  method.....");  
  136.         return null ;  
  137.     }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值