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);
}
}
运行结果: