Spring--AOP动态代理之CGLIB动态代理

1.CGLIB动态代理概述

CGLIB(Code Generation Library)是一个开源项目

CGLIB和JDK动态代理一样都是动态代理,`但是CGLIB代理没有接口的类

CGLIB代理没有接口的类 ,在JVM动态的为这个代理创建一个子类,子类重写父类方法,并且调用父类方法,在父类方法执行之前,之后,异常,最终做增强

Spring默认已经集成CGLIB代理,直接可以使用即可,不用拷贝任何jar包

image

创建方式:在获取代理类的方法中

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)动态代理的最小单位是类(所有类中的方法都会被处理);


原文:https://blog.csdn.net/Apple_Andy/article/details/108126433
作者:pple_Andy