目录
Cglib代理
子类代理,在内存中构建一个子类对象从而实现对目标对象的扩展。
Cglib代理适用场景
有一个目标对象,但是没有接口
import org.springframework.cglib.proxy.Enhancer;
//代理工厂提供获取代理的方法
public class CglibProxyFactory {
public static <T> T getProxyInstance(T t) {
//使用Cglib生成子类代理步骤
Enhancer enhancer = new Enhancer();
//指定生成哪个类的代理
enhancer.setSuperclass(t.getClass());
//设置回调(就是想当于设置调用目标对象方法时会进入MyMethodInterceptor的intercept方法)
enhancer.setCallback(new MyMethodInterceptor());
//创建子类代理对象
return (T) enhancer.create();
}
}
//新建增强类实现 MethodInterceptor
public class MyMethodInterceptor implements MethodInterceptor {
/**
*前三个参数和InvocationHandler里面的invoke方法参数一样
* @param o:生成的Cglib代理对象
* @param method:被拦截的方法
* @param objects:被拦截的方法的参数
* @param methodProxy:表示可以触发父类的方法的方法代理对象
* @return
* @throws Throwable
*/
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("开始事务---》");
//是Cglib代理
System.out.println(o.getClass());
//父类是目标对象,即Cglib的代理默认都继承自目标对象,是目标对象的子类
System.out.println(o.getClass().getSuperclass());
//指调用o的父类的方法,o的父类即是代理对象的父类,即被代理的对象,即目标对象。
//调用被代理对象的方法
Object obj = methodProxy.invokeSuper(o, objects);
System.out.println("提交事务---》");
return obj;
}
}
测试:
public class TestCglib {
public static void main(String[] args) {
UserService userService = new UserService();
UserService proxyInstance = CglibProxyFactory.getProxyInstance(userService);
proxyInstance.saveUser();
}
}
运行结果:
注意事项
- 有final修饰的类不可以被代理(因为不能有子类)
- final或static修饰的方法不可以被拦截
有final修饰的类
public final class UserService {
public void saveUser() {
System.out.println("保存数据---》" + new User());
}
}
运行上面测试代码,报如下异常
有final或static修饰的方法:
public class UserService {
public final void saveUser() {
System.out.println("保存数据---》" + new User());
}
}
public class UserService {
public static void saveUser() {
System.out.println("保存数据---》" + new User());
}
}
运行上面测试代码,结果并没有被拦截: