当前位置:  首页>> 技术小册>> Spring AOP 编程思想(下)

CGLIB AopProxy实现 - CglibAopProxy

在深入探讨Spring AOP(面向切面编程)的广阔领域中,CGLIB(Code Generation Library)作为一种强大的字节码生成库,扮演着至关重要的角色,尤其是在处理那些不能通过JDK动态代理实现的场景时,如目标类没有实现任何接口。CglibAopProxy正是Spring框架中利用CGLIB技术实现AOP代理的一个关键类。本章将详细解析CglibAopProxy的工作原理、核心方法、以及它是如何与Spring AOP体系集成的。

一、引言

在Java中,实现AOP主要有两种方式:JDK动态代理和CGLIB。JDK动态代理要求目标对象必须实现至少一个接口,而CGLIB则通过继承目标类来创建代理对象,从而允许对任何类的方法进行拦截。这种灵活性使得CGLIB在Spring AOP中尤为重要,尤其是在处理那些没有实现接口的类时。

二、CGLIB AopProxy概述

CglibAopProxy是Spring AOP框架中用于创建基于CGLIB的AOP代理的核心类。它继承自AbstractAopProxy,并实现了AopProxy接口,该接口定义了创建代理对象的方法。CglibAopProxy主要负责以下任务:

  1. 代理对象的生成:通过CGLIB技术动态生成目标类的子类,作为代理对象。
  2. 方法拦截:在代理对象中,通过覆写目标类的方法并插入增强逻辑(Advice),实现对方法调用的拦截。
  3. 回调接口实现:实现CGLIB提供的MethodInterceptor接口,以便在执行目标方法前后插入自定义逻辑。

三、CglibAopProxy的核心组件

1. Enhancer

CGLIB的Enhancer类是创建代理类的关键。CglibAopProxy利用Enhancer来生成目标类的子类,并设置必要的回调接口,如MethodInterceptor

2. CallbackCallbackFilter
  • Callback:在CGLIB中,Callback是一个接口,代表了在代理类中可能被调用的回调方法。MethodInterceptor就是一种特殊的Callback,用于拦截方法调用。
  • CallbackFilter:用于决定在代理类的每个方法上应该使用哪个Callback。在CglibAopProxy中,这通常用于区分哪些方法需要被拦截,哪些不需要。
3. Dispatcher

虽然CglibAopProxy主要依赖MethodInterceptor,但Dispatcher(如NoOpDispatcherDefaultingToTarget等)也在某些场景下发挥作用,特别是在处理字段访问或静态方法调用时。

四、CglibAopProxy的工作流程

  1. 创建Enhancer实例CglibAopProxy首先创建一个Enhancer实例,并配置其属性,如父类(目标类)、回调接口(主要是MethodInterceptor)等。

  2. 设置Callback和CallbackFilter:根据Spring AOP的配置,CglibAopProxy设置适当的CallbackCallbackFilter。对于需要被拦截的方法,使用包含增强逻辑的MethodInterceptor;对于不需要拦截的方法,则可能使用NoOp回调。

  3. 生成代理类:通过调用EnhancercreateClass方法,生成目标类的子类,即代理类。这个过程中,CGLIB会动态地编译和加载这个类。

  4. 创建代理对象:使用Enhancer生成的代理类来创建代理对象实例。这个实例会继承目标类的所有非final方法和字段。

  5. 方法调用拦截:当代理对象的方法被调用时,根据CallbackFilter的决策,如果该方法需要被拦截,则调用MethodInterceptorintercept方法。在intercept方法中,可以执行前置通知(Before Advice)、调用目标方法、执行后置通知(After Advice)等操作。

五、CglibAopProxy的关键方法

  • getProxy(ClassLoader classLoader):此方法负责根据给定的类加载器创建代理对象。它首先通过Enhancer生成代理类,然后创建并返回代理对象实例。

  • setCallbacks(Callback[] callbacks):此方法用于设置代理类应使用的回调接口数组。在Spring AOP中,这个数组通常包含了一个MethodInterceptor实例,用于拦截方法调用。

  • setCallbackFilter(CallbackFilter filter):此方法用于设置回调过滤器,它决定了代理类中每个方法调用时应该使用哪个回调接口。

六、CglibAopProxy的优缺点

优点

  • 灵活性高:能够代理没有实现接口的类。
  • 功能强大:通过继承目标类,可以在不修改源代码的情况下增加新功能。

缺点

  • 性能开销:相比JDK动态代理,CGLIB通过继承方式生成代理类,可能引入额外的性能开销,特别是在代理类层次结构较深时。
  • 最终类问题:如果目标类是final的,则无法被CGLIB代理。
  • 构造函数限制:CGLIB代理的构造函数调用不会被拦截,这可能限制了在构造函数中进行的依赖注入等操作。

七、总结

CglibAopProxy作为Spring AOP中CGLIB代理实现的核心类,通过继承目标类并覆写其方法,实现了对方法调用的拦截和增强。它的灵活性和强大功能使得Spring AOP能够处理更广泛的场景,尤其是在面对没有实现接口的类时。然而,开发者在使用时也需要注意其可能带来的性能开销和限制。通过对CglibAopProxy的深入理解,我们可以更好地利用Spring AOP的强大功能,为应用程序提供灵活的切面编程支持。


该分类下的相关小册推荐: