做一个合格的程序猿之浅析Spring AOP源码(十三) jdk的动态代理和cglib的代理

来源:互联网 发布:软考 数据库系统工程师 编辑:程序博客网 时间:2024/06/13 21:02

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


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


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


首先jdk的动态代理:

首先定义一个网店的接口

package org.study.spring.aop.jdkdynamicproxy;/** *  * jdk的动态代理必须是面向接口的 * 定义一个淘宝网店的接口 * @author lyncc * */public interface OnlineShop {    /**     * 网店抽象:用户给钱买东西     * @param money     */void sellSomething(double money);}
然后一个网店是卖茶叶的,实现该接口

package org.study.spring.aop.jdkdynamicproxy;public class TeaOnlineShop implements OnlineShop{public void sellSomething(double money) {System.out.println("shop say    :you give me "+money +"$ and I sell you some tea");}}
好了,淘宝代理出场了

package org.study.spring.aop.jdkdynamicproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/** * 淘宝代理 jdk的代理要实现InvocationHandler的接口 * @author lyncc * */public class TaobaoProxy implements InvocationHandler{    /**     * 被代理的对象     */ private Object proxied;         public TaobaoProxy(Object proxied){       this.proxied = proxied;    }  /**  * InvocationHandler的核心方法,invoke方法  */public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {    //马云爸爸表示收到的钱先放在淘宝,来提高GMVSystem.out.println("taobao say:    "+args[0]+"$ money temp save to taobao to increase my gmv");return method.invoke( proxied, args);  }}
测试类

package org.study.spring.aop.jdkdynamicproxy;import java.lang.reflect.Proxy;import org.junit.Test;public class JdkDynamicProxyTest {@Testpublic void test1(){     //被代理的对象 TeaOnlineShop teaShop = new TeaOnlineShop();    //Proxy 入参三个 加载器,class文件, 实现innovationhandler接口的代理对象 OnlineShop shop = (OnlineShop)Proxy.newProxyInstance(OnlineShop.class.getClassLoader(),      new Class[]{OnlineShop.class},      new TaobaoProxy(teaShop));          shop.sellSomething(20d);}}
运行结果:




CGLIB的实现

package org.study.spring.aop.cglib;/** * cglib不需要定义接口,直接给出具体实现 * @author lyncc */public class TeaOnlineShop{public void sellSomething(double money) {System.out.println("shop say    :you give me "+money +"$ and I sell you some tea");}}

taobaoProxy

package org.study.spring.aop.cglib;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;/** * cglib要实现MethodInterceptor接口 * @author lyncc * */public class TaobaoProxy implements MethodInterceptor{private Enhancer enhancer = new Enhancer();  public Object getProxy(Class clazz){    //用enhancer 重新编制传入的class的对象  enhancer.setSuperclass(clazz);    //回调实现CallBack接口的类(MethodInterceptor基础于CallBack)此处就是回调TaobaoProxy  enhancer.setCallback(this);    return enhancer.create();   }/** * 拦截器 */public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {  System.out.println("taobao say:    "+args[0]+"$ money temp save to taobao to increase my gmv");    Object result = proxy.invokeSuper(obj, args);    return result; } }
测试

package org.study.spring.aop.cglib;import org.junit.Test;public class CgLibProxyTest {@Testpublic void test(){TaobaoProxy proxy = new TaobaoProxy();  //通过生成子类的方式创建代理类  TeaOnlineShop shopProxy = (TeaOnlineShop)proxy.getProxy(TeaOnlineShop.class);  shopProxy.sellSomething(21d); }} 

运行结果:





0 0
原创粉丝点击