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 { //马云爸爸表示收到的钱先放在淘宝,来提高GMV System.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 { @Test public 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 { @Test public void test(){ TaobaoProxy proxy = new TaobaoProxy(); //通过生成子类的方式创建代理类 TeaOnlineShop shopProxy = (TeaOnlineShop)proxy.getProxy(TeaOnlineShop.class); shopProxy.sellSomething(21d); } }
运行结果: