1.CGLIB动态代理概述
CGLIB(Code Generation Library)是一个开源项目
CGLIB和JDK动态代理一样都是动态代理,`但是CGLIB代理没有接口的类
CGLIB代理没有接口的类
,在JVM动态的为这个代理创建一个子类,子类重写父类方法,并且调用父类方法,在父类方法执行之前,之后,异常,最终做增强
Spring默认已经集成CGLIB代理,直接可以使用即可,不用拷贝任何jar包
创建方式:在获取代理类的方法中
1)创建Enhancer CGLIB代理对象
Enhancer enhancer = new Enhancer();
2)设置类加载器
enhancer.setClassLoader(Thread.currentThread().getContextClassLoader());
3)设置被代理对象的字节码
//3.设置被代理对象的字节码
enhancer.setSuperclass(target.getClass());
4)设置增强的逻辑
//4.设置增强逻辑
enhancer.setCallback(new org.springframework.cglib.proxy.InvocationHandler() {
}
5)创建代理对象
Object proxyObject = enhancer.create();
完整代码
@Component
public class CGLIBDynamicProxyObjectHandler {
/*
* 1,被代理的对象(真实对象),当前不要注入接口,因为当前JDK动态代理底层使用时接口产生代理对象
* 只有注入实现类才能获取对应的接口
* 如果直接注入接口,接口不可能获取接口的
*/
@Autowired
private UserServiceImpl target;
//2,要增强的功能,当前场景就是模拟的事务管理器
@Autowired
private TransactionManagerHandler txManager;
//返回代理对象的方法
public <T> T getProxyObject(Class<T> clz) {
//使用CGLIB的 Enhancer 对象创建代理对象
//1.创建Enhance对象
Enhancer enhancer = new Enhancer();
//2.设置类加载器
enhancer.setClassLoader(Thread.currentThread().getContextClassLoader());
//3.设置被代理对象的字节码
enhancer.setSuperclass(target.getClass());
//4.设置增强逻辑
enhancer.setCallback(new org.springframework.cglib.proxy.InvocationHandler() {
/**
* 在此方法中完成增强的逻辑
*
* 1,在方法内部执行被代理对象的方法,并返回执行结果
* 2,在被代理对象方法执行之前,之后,异常,最终做增强(模拟的事务管理器的功能)
*
* @param proxy 创建的代理对象
* @param method 被代理对象要执行的对应的方法
* @param args 被代理对象执行的对应的方法的参数
* @return 返回的是被代理对象方法执行的结果
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method);
if("toString".equals(method.getName())) {
return method.invoke(target, args);
}else if("hashCode".equals(method.getName())) {
return method.invoke(target, args);
}
Object result =null;
try {
//开启事务
txManager.begin();
//执行被代理对象的方法
result = method.invoke(target, args);
//提交事务
txManager.commit();
} catch (Exception e) {
//回滚事务
txManager.rollback();
}finally {
//释放资源
txManager.close();
}
return result;
}
});
//5.创建代理对象
Object proxyObject = enhancer.create();
return (T) proxyObject;
}
}
优缺点
优点:1)能够在程序运行的时候动态的生成代理对象,从而在不需要修改源代码的基础上,对已有的方法进行增强
2)可以代理没有接口的类,在jvm中动态的为这个真实对象创建了一个子类,子类中重写父类方法,并且调用父类方法,在父类方法执行之前,之后,异常,最终做增强
缺点:1)要求类不能是final的,要代理的方法要是非final、非static、非private的。
2)动态代理的最小单位是类(所有类中的方法都会被处理);
原文:Spring--AOP动态代理之CGLIB动态代理_Catalina_yep的博客-CSDN博客
作者:pple_Andy