动态代理常用的有两种方式:
(1)基于接口的动态代理
提供者:JDK官方的Proxy类,这种方式主要使用的是java的反射机制(即java.lang.reflect包)。
要求:被代理类最少实现一个接口
解析:
动态代理:程序运行时,使用JDK提供工具类(Proxy),动态创建一个类,此类一般用于代理。
代理:你 -- 代理(增强) -- 厂商
代理类:目标类:被代理的
动态代理使用前提:必须有接口
Object proxyObj = Proxy.newProxyInstance(参数1,参数2,参数3);
参数1:ClassLoader,负责将动态创建类,加载到内存。当前类.class.getClassLoader();
参数2:Class[] interfaces ,代理类需要实现的所有接口(确定方法),被代理类实例.getClass().getInterfaces();
参数3:InvocationHandler, 请求处理类,代理类不具有任何功能,代理类的每一个方法执行时,调用处理类invoke方法。
invoke(Object proxy ,Method ,Object[] args)
参数1:代理实例
参数2:当前执行的方法
参数3:方法实际参数。
核心代码实现:
package cn.shuai.service.proxy;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;
public class UserServiceProxyFactory<T> implements InvocationHandler{
//被代理对象
private T target;
public UserServiceProxyFactory(T target) {
this.target = target;
}
//动态代理技术=>代理UserService
@SuppressWarnings("unchecked")
public T getUserServiceProxy() {
// 参数1:类加载器. => 用来加载动态产生的代理类
// 参数2:填写代理类要实现的接口(可以是多个)
// 参数3:在代理中需要做什么 => 接口回调来表示在代理类中要做的功能
return (T)Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
target.getClass().getInterfaces(), this);
}
@Override
//参数1:动态代理对象 //参数2:当前的业务方法 //参数3:业务方法的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//开启事务(这里代码用输出语句代替)
System.out.println("事务开启了");
//调用原有业务方法
Object invoke = method.invoke(target, args);
//提交或回滚事务(这里代码用输出语句代替)
System.out.println("提交或回滚事务");
return invoke;
}
}
(2)基于子类的动态代理
提供者:第三方的CGLib,如果报asmxxx异常,需要导入asm.jar。
要求:被代理的类不能用final修饰(final修饰后为最终类,不会有子类)
解析:用到的方法:create(Class, Callback)
方法中用到的参数:Class:被代理对象的字节码。Callback:如何代理。
核心代码实现:
package cn.shuai.service.proxy;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
//CGlib代理
public class UserServiceProxyFactory2<T> implements MethodInterceptor{
private T target;
public UserServiceProxyFactory2(T target) {
this.target = target;
}
@SuppressWarnings("unchecked")
public T getUserServiceProxy(){
Enhancer enhancer = new Enhancer();
//指定代理类的父类(被代理的对象)
enhancer.setSuperclass(target.getClass());
//2 指定代理方法如何实现(接口回调)
enhancer.setCallback(this);
return (T) enhancer.create();
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("事务开启了");
//调用原业务方法
Object invokeSuper = methodProxy.invokeSuper(proxy, args);
System.out.println("事务提交或会滚了");
return invokeSuper;
}
}