JDK代理:
基于接口的动态代理技术
准备目标接口,目标接口实现,增强方法
/**
* @description: 目标接口
* @Author C_Y_J
* @create 2021-03-01 09:37
**/
public interface TargetInterface {
void save();
}
/**
* @description: 目标接口的实现
* @Author C_Y_J
* @create 2021-03-01 09:38
**/
public class TargetInterfaceImpl implements TargetInterface {
@Override
public void save() {
System.out.println("目标接口的实现 run ...");
}
}
/**
* @description: 增强方法
* @Author C_Y_J
* @create 2021-03-01 09:39
**/
public class Advice {
public void before(){
System.out.println("前置增强");
}
public void afterReturning(){
System.out.println("后置增强");
}
}
准备基于jdk动态代理对象
/**
* @description: 动态代理对象测试
* @Author C_Y_J
* @create 2021-03-01 09:42
**/
public class ProxyJdkTest {
public static void main(String[] args) {
TargetInterfaceImpl targetInterface = new TargetInterfaceImpl();
Advice advice = new Advice();
/*
* 在这里需要三个参数
* Proxy.newProxyInstance 返回就是产生的动态代理对象,返回值必须要用TargetInterface 接口接收
* */
TargetInterface proxyInstance = (TargetInterface) Proxy.newProxyInstance(
//(1)目标对象 类加载器
targetInterface.getClass().getClassLoader(),
//(2)目标对象 相同接口 字节码数组
targetInterface.getClass().getInterfaces(),
new InvocationHandler() {
/*
*(3)
* 调用动态代理对象的任何方法,实际上调用的是底下的invoke方法
* proxy:代理对象
* method:目标方法对象
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//(5)前置增强
advice.before();
//(4)有人看到这里目标方法调用了invoke方法,会认为是回调!!!
// 上面的invoke是动态代理对象的invoke,下面的invoke是反射
method.invoke(targetInterface, args);
//(6)后置增强
advice.afterReturning();
return null;
}
}
);
//测试
proxyInstance.save();
}
}
Proxy.newProxyInstance() 需要三个参数:(1)目标对象 类加载器、(2)目标对象 相同接口 字节码数组、(3)new InvocationHandler()。
Proxy.newProxyInstance() 返回就是产生的动态代理对象,返回值必须要用接口接收,因为要保证动态代理对象和目标接口实现是属于兄弟关系
cglib代理:
导入相关依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
</dependencies>
在spring-context下有spring-core依赖,查看发现已经加入了cglib的源码**
准备目标方法,增强方法。代码和上面一样,我不重复写
准备基于cglib动态代理对象
/**
* @description: 动态代理对象测试
* @Author C_Y_J
* @create 2021-03-01 09:42
**/
public class ProxyCglibTest {
public static void main(String[] args) {
TargetInterfaceImpl targetInterface = new TargetInterfaceImpl();
Advice advice = new Advice();
//1、创建增强器
Enhancer enhancer = new Enhancer();
//2、设置父类(其实就是目标类)
enhancer.setSuperclass(TargetInterfaceImpl.class);
//3、设置回调 setCallback() 需要的参数是Callback接口,我们用Callback接口下的MethodInterceptor子接口
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//前置方法
advice.before();
//目标方法
method.invoke(targetInterface, args);
//后置方法
advice.afterReturning();
return null;
}
});
//4、创建代理对象,返回值可以用TargetInterfaceImpl 子类接收
TargetInterfaceImpl proxy = (TargetInterfaceImpl) enhancer.create();
//测试
proxy.save();
}
}
enhancer.setSuperclass(TargetInterfaceImpl.class) 设置父类(其实就是目标类)
enhancer.setCallback() 设置回调 setCallback() 需要的参数是Callback接口,我们用Callback接口下的MethodInterceptor子接口
enhancer.create() 返回值可以用TargetInterfaceImpl 子类接收,因为动态代理对象和目标对象是属于父子关系