本文共 2398 字,大约阅读时间需要 7 分钟。
在学习 Spring AOP 的过程中,我们需要深入理解其自动代理机制。Spring AOP 的核心是通过动态代理实现方法拦截和方法替换,这一过程主要由 AbstractAutoProxyCreator 类负责。在前面的文章中,我们分析了自动代理的入口和筛选Advisor的过程。本文将深入探讨如何为目标Bean创建代理对象。
在 AbstractAutoProxyCreator 类的 wrapIfNecessary 方法中,代理对象的创建主要分为以下几个步骤:
检查是否需要代理
首先,判断当前Bean是否需要代理。如果Bean已经被代理过(targetSourcedBeans 中存在)或不需要代理(advisedBeans 中标记为 false),则直接返回Bean。 获取目标类
如果需要代理,则获取目标Bean的类,并检查是否需要进行类代理(CGLIB动态代理)。默认情况下,proxyTargetClass 为 false,表示优先使用JDK动态代理,但如果目标类没有实现可代理的接口,则会切换到CGLIB动态代理。 获取适用的Advisor
调用getAdvicesAndAdvisorsForBean 方法,获取能够应用于目标Bean的所有Advisor。这些Advisor会根据 @Order 注解进行排序,优先级为:AspectJAfterThrowingAdvice > AspectJAfterReturningAdvice > AspectJAfterAdvice > AspectJAroundAdvice > AspectJMethodBeforeAdvice。 创建代理对象
如果有适用的Advisor,则通过createProxy 方法创建代理对象。以下是具体的实现细节: 代理对象的创建主要由 ProxyFactory 类负责。ProxyFactory 类的作用是创建动态代理对象,具体由 DefaultAopProxyFactory 实现。
DefaultAopProxyFactory 根据以下条件选择代理类型:
proxy-target-class 为 false,优先使用JDK动态代理。如果目标类没有实现可代理的接口,则切换到CGLIB动态代理。proxy-target-class 为 true,优先使用CGLIB动态代理。如果目标类本身是一个接口,则仍使用JDK动态代理。JdkDynamicAopProxy 和 ObjenesisCglibAopProxy 是两种主要的动态代理实现类。
JdkDynamicAopProxy 实现了 InvocationHandler 接口,通过 Proxy.newProxyInstance 方法创建代理对象。DynamicAdvisedInterceptor 实现。ObjenesisCglibAopProxy 通过 Enhancer 创建代理类。CGLIB会生成目标类的超类,避免直接修改目标类。无论是JDK动态代理还是CGLIB动态代理,代理对象都实现了 InvocationHandler 接口,用于拦截目标对象的方法调用。拦截器的逻辑主要集中在以下几个方面:
equals 和 hashCode 方法中添加代理对象的信息。在CGLIB动态代理中,Callback 数组用于定义方法拦截器的逻辑。具体来说,Callback 的类型和顺序决定了拦截器的行为。以下是常见的 Callback 类型:
AOP_PROXY:进行AOP代理的通用拦截器。INVOKETARGET:执行目标方法。NO_OVERRIDE:空的 Callback,用于不需要拦截的方法(如 finalize())。DISPATCH_TARGET:目标对象调度器,用于获取目标对象。DISPATCH_ADVISED:配置管理器的调度器,用于执行 AdvisedSupport 的方法。Spring AOP 的自动代理过程可以分为以下几个关键步骤:
ClassFilter 和 MethodMatcher 确定哪些Advisor适用于目标Bean。ProxyFactory 创建代理对象。其中,CGLIB动态代理的实现相对复杂,涉及 Objenesis 库的实例化和 Callback 的配置。以下是两种动态代理的主要区别:
通过本文的分析,我们可以清晰地看到Spring AOP如何在背后为Bean创建代理对象,从而实现AOP的功能。如果需要进一步理解动态代理的实现细节,可以继续阅读下一篇文章,探讨 DynamicAdvisedInterceptor 拦截器的工作原理。
转载地址:http://gksyz.baihongyu.com/