浅析Spring AOP源码(十三) jdk的动态代理和cglib的代理

spring AOP的核心就是动态代理,我们先来准备下动态代理的知识的储备


  动态代理,顾名思义,就是为一个真实对象生成一个代理的对象,生活中,这种模式也是很常见,例如,淘宝,就是一个代理,很多网店,依托于淘宝,可以更好的卖出很多的产品,但淘宝可能会额外的多做一点事情,这样就会产生双赢的局面


好了,我们现在就根据上面的背景,写下两种代理:


首先jdk的动态代理:

首先定义一个网店的接口

[java]  view plain   copy
  1. package org.study.spring.aop.jdkdynamicproxy;  
  2.   
  3. /** 
  4.  *  
  5.  * jdk的动态代理必须是面向接口的 
  6.  * 定义一个淘宝网店的接口 
  7.  * @author lyncc 
  8.  * 
  9.  */  
  10. public interface OnlineShop {  
  11.       
  12.     /** 
  13.      * 网店抽象:用户给钱买东西 
  14.      * @param money 
  15.      */  
  16.     void sellSomething(double money);  
  17.   
  18. }  
然后一个网店是卖茶叶的,实现该接口

[java]  view plain   copy
  1. package org.study.spring.aop.jdkdynamicproxy;  
  2.   
  3. public class TeaOnlineShop implements OnlineShop{  
  4.   
  5.     public void sellSomething(double money) {  
  6.         System.out.println("shop say    :you give me "+money +"$ and I sell you some tea");  
  7.     }  
  8.   
  9. }  
好了,淘宝代理出场了

[java]  view plain   copy
  1. package org.study.spring.aop.jdkdynamicproxy;  
  2.   
  3. import java.lang.reflect.InvocationHandler;  
  4. import java.lang.reflect.Method;  
  5.   
  6. /** 
  7.  * 淘宝代理 jdk的代理要实现InvocationHandler的接口 
  8.  * @author lyncc 
  9.  * 
  10.  */  
  11. public class TaobaoProxy implements InvocationHandler{  
  12.       
  13.     /** 
  14.      * 被代理的对象 
  15.      */  
  16.      private Object proxied;     
  17.        
  18.      public TaobaoProxy(Object proxied){     
  19.         this.proxied = proxied;     
  20.      }   
  21.   
  22.      /** 
  23.       * InvocationHandler的核心方法,invoke方法 
  24.       */  
  25.     public Object invoke(Object proxy, Method method, Object[] args)  
  26.             throws Throwable {  
  27.         //马云爸爸表示收到的钱先放在淘宝,来提高GMV  
  28.         System.out.println("taobao say:    "+args[0]+"$ money temp save to taobao to increase my gmv");  
  29.           
  30.         return method.invoke( proxied, args);    
  31.     }  
  32.   
  33. }  
测试类

[java]  view plain   copy
  1. package org.study.spring.aop.jdkdynamicproxy;  
  2.   
  3. import java.lang.reflect.Proxy;  
  4.   
  5. import org.junit.Test;  
  6.   
  7. public class JdkDynamicProxyTest {  
  8.       
  9.       
  10.     @Test  
  11.     public void test1(){  
  12.          //被代理的对象  
  13.          TeaOnlineShop teaShop = new TeaOnlineShop();     
  14.          //Proxy 入参三个 加载器,class文件, 实现innovationhandler接口的代理对象  
  15.          OnlineShop shop = (OnlineShop)Proxy.newProxyInstance(OnlineShop.class.getClassLoader(),   
  16.              new Class[]{OnlineShop.class},   
  17.              new TaobaoProxy(teaShop));  
  18.                    
  19.          shop.sellSomething(20d);  
  20.     }  
  21.   
  22. }  
运行结果:




CGLIB的实现

[java]  view plain   copy
  1. package org.study.spring.aop.cglib;  
  2.   
  3. /** 
  4.  * cglib不需要定义接口,直接给出具体实现 
  5.  * @author lyncc 
  6.  */  
  7. public class TeaOnlineShop{  
  8.   
  9.     public void sellSomething(double money) {  
  10.         System.out.println("shop say    :you give me "+money +"$ and I sell you some tea");  
  11.     }  
  12.   
  13. }  

taobaoProxy

[java]  view plain   copy
  1. package org.study.spring.aop.cglib;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import net.sf.cglib.proxy.Enhancer;  
  6. import net.sf.cglib.proxy.MethodInterceptor;  
  7. import net.sf.cglib.proxy.MethodProxy;  
  8.   
  9. /** 
  10.  * cglib要实现MethodInterceptor接口 
  11.  * @author lyncc 
  12.  * 
  13.  */  
  14. public class TaobaoProxy implements MethodInterceptor{  
  15.       
  16.     private Enhancer enhancer = new Enhancer();    
  17.       
  18.     public Object getProxy(Class clazz){    
  19.       //用enhancer 重新编制传入的class的对象  
  20.       enhancer.setSuperclass(clazz);    
  21.       //回调实现CallBack接口的类(MethodInterceptor基础于CallBack)此处就是回调TaobaoProxy  
  22.       enhancer.setCallback(this);    
  23.       return enhancer.create();    
  24.      }  
  25.   
  26.     /** 
  27.      * 拦截器 
  28.      */  
  29.     public Object intercept(Object obj, Method method, Object[] args,  
  30.             MethodProxy proxy) throws Throwable {  
  31.           
  32.           System.out.println("taobao say:    "+args[0]+"$ money temp save to taobao to increase my gmv");  
  33.             
  34.           Object result = proxy.invokeSuper(obj, args);    
  35.           return result;   
  36.     }      
  37.   
  38. }  
测试

[java]  view plain   copy
  1. package org.study.spring.aop.cglib;  
  2.   
  3. import org.junit.Test;  
  4.   
  5. public class CgLibProxyTest {  
  6.       
  7.     @Test  
  8.     public void test(){  
  9.         TaobaoProxy proxy = new TaobaoProxy();    
  10.         //通过生成子类的方式创建代理类    
  11.         TeaOnlineShop shopProxy = (TeaOnlineShop)proxy.getProxy(TeaOnlineShop.class);    
  12.         shopProxy.sellSomething(21d);   
  13.     }  
  14.   
  15. }   

运行结果:

你可能感兴趣的:(浅析Spring AOP源码(十三) jdk的动态代理和cglib的代理)