码迷,mamicode.com
首页 > 编程语言 > 详细

Spring AOP 实现原理(三) 使用 使用 CGLIB 生成代理类

时间:2015-05-30 22:42:18      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:spring   aop   cglib   

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 生成代理类

标签:spring   aop   cglib   

原文地址:http://blog.csdn.net/lovesomnus/article/details/46278807

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!