CGLIB(Code Generation Library),简单来说,就是一个代码生成类库。它可以在运行时候动态是生成某个类的子类。
此处使用前面定义的 Chinese 类,现在改为直接使用 CGLIB 来生成代理,这个代理类同样可以实现 Spring AOP 代理所达到的效果。
下面先为 CGLIB 提供一个拦截器实现类:public class AroundAdvice implements MethodInterceptor { public Object intercept(Object target, Method method , Object[] args, MethodProxy proxy) throws java.lang.Throwable { System.out.println("执行目标方法之前,模拟开始事务 ..."); // 执行目标方法,并保存目标方法执行后的返回值 Object rvt = proxy.invokeSuper(target, new String[]{"被改变的参数"}); System.out.println("执行目标方法之后,模拟结束事务 ..."); return rvt + " 新增的内容"; } }
上面这个 AroundAdvice.java 的作用就像前面介绍的 Around Advice,它可以在调用目标方法之前、调用目标方法之后织入增强处理。
接下来程序提供一个 ChineseProxyFactory 类,这个 ChineseProxyFactory 类会通过 CGLIB 来为 Chinese 生成代理类:
public class ChineseProxyFactory { public static Chinese getAuthInstance() { Enhancer en = new Enhancer(); // 设置要代理的目标类 en.setSuperclass(Chinese.class); // 设置要代理的拦截器 en.setCallback(new AroundAdvice()); // 生成代理类的实例 return (Chinese)en.create(); } }
运行上面主程序,看到如下输出结果:
执行目标方法之前,模拟开始事务 ... -- 正在执行 sayHello 方法 -- 执行目标方法之后,模拟结束事务 ... 被改变的参数 Hello , CGLIB 新增的内容 执行目标方法之前,模拟开始事务 ... 我正在吃 : 被改变的参数 执行目标方法之后,模拟结束事务 .. class lee.Chinese$$EnhancerByCGLIB$$4bd097d9
从上面输出结果来看,CGLIB 生成的代理完全可以作为 Chinese 对象来使用,而且 CGLIB 代理对象的 sayHello()、eat() 两个方法已经增加了事务控
制(只是模拟),这个 CGLIB 代理其实就是 Spring AOP 所生成的 AOP 代理。
通过程序最后的输出,不难发现这个代理对象的实现类是 lee.Chinese$$EnhancerByCGLIB$$4bd097d9,这就是 CGLIB 所生成的代理类,这个代理
类的格式与前面 Spring AOP 所生成的代理类的格式完全相同。
这就是 Spring AOP 的根本所在:Spring AOP 就是通过 CGLIB 来动态地生成代理对象,这个代理对象就是所谓的 AOP 代理,而 AOP 代理的方法则
通过在目标对象的切入点动态地织入增强处理,从而完成了对目标方法的增强。
接下来程序提供一个 ChineseProxyFactory 类,这个 ChineseProxyFactory 类会通过 CGLIB 来为 Chinese 生成代理类:上面粗体字代码就是使用
CGLIB 的 Enhancer 生成代理对象的关键代码,此时的 Enhancer 将以 Chinese 类作为目标类,以 AroundAdvice 对象作为“Advice”,程序将会生成
一个 Chinese 的子类,这个子类就是 CGLIB 生成代理类,它可作为 Chinese 对象使用,但它增强了Chinese 类的方法。
测试 Chinese 代理类的主程序如下:
public class Main { public static void main(String[] args) { Chinese chin = ChineseProxyFactory.getAuthInstance(); System.out.println(chin.sayHello("孙悟空")); chin.eat("西瓜"); System.out.println(chin.getClass()); } }
AOP 广泛应用于处理一些具有横切性质的系统级服务,AOP 的出现是对 OOP 的良好补充,它使得开发者能用更优雅的方式处理具有横切性质的服
务。不管是那种 AOP 实现,不论是 AspectJ、还是 Spring AOP,它们都需要动态地生成一个 AOP 代理类,区别只是生成 AOP 代理类的时机不同:
AspectJ 采用编译时生成 AOP 代理类,因此具有更好的性能,但需要使用特定的编译器进行处理;而 Spring AOP 则采用运行时生成 AOP 代理类,
因此无需使用特定编译器进行处理。由于 Spring AOP 需要在每次运行时生成AOP 代理,因此性能略差一些。
Spring AOP 实现原理(三) 使用 使用 CGLIB 生成代理类
原文地址:http://blog.csdn.net/lovesomnus/article/details/46278807