《Spring技术内幕》学习笔记8——创建AOP代理对象并对目标对象切面拦截

本文详细介绍了Spring AOP的底层实现,包括ProxyConfig、AdvisedSupport、ProxyCreatorSupport等核心类的作用,以及ProxyFactoryBean如何创建AOP代理对象。文章深入分析了Singleton和Prototype模式下代理对象的生成,并揭示了DefaultAopProxyFactory和CGLIB在创建AOP代理中的角色,最后探讨了AOP拦截器链的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Spring AOP的底层实现常用类:

分析Spring AOP的底层实现首先要从ProxyConfig类开始,ProxyConfig是所有产生Spring AOP代理对象的基类,它是一个数据类,主要为其AOP代理对象工厂实现类提供配置属性。根据ProxyConfig的继承体系分析创建AOP代理常用类的作用:

(1).AdvisedSupportProxyConfig的子类,它封装了AOP中对通知(Advice)和通知器(Advisor)的相关操作,这些操作对于不同的AOP的代理对象的生成都是一样的,但对于具体的AOP代理对象的创建,AdvisedSupport把它交给子类去实现。

(2).ProxyCreatorSupportAdvisedSupport的子类,它是其子类创建AOP代理对象的一个辅助类,提供不同AOP代理对象生成的通用操作,具体的AOP代理对象生成,由ProxyCreatorSupport的子类完成。

(3).创建AOP代理对象的类:

ProxyCreatorSupport3个子类,分别创建不同的AOP代理对象,具体如下:

a.AspectJProxyFactory:主要用于创建AspectJAOP应用,起到集成SpringAspectJ的作用。

b.ProxyFactory:创建编程式的Spring AOP应用。

c.ProxyFactoryBean:创建声明式的Spring AOP应用。

2.声明式Spring AOP代理工厂对象ProxyFactoryBean

我们以ProxyFactoryBean为例,分析Spring AOP的实现原理,ProxyFactoryBeanSpring中一个非常灵活的创建AOP应用的底层方法,封装了AOP的主要功能。

一个简单的AOP代理工厂对象的配置如下:

3.ProxyFactoryBean生成AOPProxy代理对象:

2ProxyFactoryBean的简单配置例子我们可以看出,ProxyFactoryBean是用来配置目标对象和切面行为Advice的,ProxyFactoryBean通过其配置的拦截器名称interceptorNames即通知器Advisor将切面行为Advice应用到目标对象中。

ProxyFactoryBean中,需要为待增强目标对象目标对象生成Proxy代理对象,从而为AOP切面的编织提供基础,下面通过源码分析ProxyFactoryBean的生成AOPProxy代理对象的实现过程:

(1).ProxyFactoryBean产生代理对象的主要源码:

通过源码分析,我们了解到AOPProxyFactory实现了FactoryBean接口,所以本身也是一个Spring的工厂BeanAOP代理工厂的主要功能概况为:

a.初始化通知器链,将配置的通知器链添加到容器存放通知/通知器的集合中。

b.根据单态模式/原型模式,获取AOPProxy产生AOPProxy代理对象。

(2).AOP创建辅助器(AOPCreatorSupport)获取AOPProxy代理对象:

AOPProxyFactorygetSingletonInstancenewPrototypeInstance方法均通过调用AOPCreatorSupportcreateAopProxy()方法获取AOPProxy,主要源码如下:

通过对ProxyCreatorSupport的源码分析,我们知道真正创建AOPProxy代理对象的是DefaultAopProxyFactory类。

(3).DefaultAopProxyFactory创建AOPProxy代理对象:

DefaultAopProxyFactoryAOP创建辅助器(AOPCreatorSupport)默认的AOP代理工厂,DefaultAopProxyFactorycreateAopProxy方法实现了创建AOP代理的功能,源码如下:

通过对DefaultAopProxyFactory的源码分析,我们了解了Spring在创建AOP代理对象时,如果配置的目标类是接口,则使用JDK的动态代理机制来生成AOP代理,如果使用的不是接口,则使用CGLIB方式来生成AOP的动态代理。

4.JDK动态代理机制创建AOPProxy代理对象:

JDK的动态代理机制只能对接口起作用,即如果要对一个对象使用JDK动态代理方式生成代理对象时,该对象必须实现接口,Spring中通过JdkDynamicAopProxy类使用JDK动态代理机制生成AOPProxy代理对象,JdkDynamicAopProxy的主要源码如下:

通过上述源码分析,我们看到JdkDynamicAopProxy本身实现了InvocationHandler接口和invoke()方法,JDK的动态代理机制的工作原理是:当调用目标对象的方法时,不是直接调用目标对象,而是首先生成一个目标对象的动态代理对象,触发代理对象的invoke()方法,代理的invoke()方法才会真正调用目标对象的方法。Spring AOP的实现原理是在代理对象invoke()方法调用目标对象的方法时,调用配置的通知。

5.CglibProxyFactory创建AOPProxy代理

JDK的动态代理只能针对接口生成代理对象,对于没有实现接口的目标对象,必须通过第3方的CGLIB来生成代理对象,CglibProxyFactory创建AOPProxy代理的主要源码如下:

通过上面对CGLIB创建代理和获取回答通知的源码分析,我们了解到CGLIB在获取代理的通知时,会创建DynamicAdvisedInterceptor类,当应用调用目标对象的方法时,不是直接调用目标对象,而是通过CGLIB创建的代理对象来调用目标对象,在调用目标对象的方法时,触发DynamicAdvisedInterceptorintercept回调方法对目标对象进行处理,CGLIB回调拦截器链的源码如下:

6.目标对象方法的调用:

通过上面45分别对JdkDynamicAopProxyCglib2AopProxy创建AOPProxy代理对象,以及对目标对象的通知器回调我们可以看出,当目标对象没有配置通知器时,代理对象直接调用目标对象的方法,下面具体分析直接调用目标对象方法的过程:

(1).JdkDynamicAopProxy直接调用目标对象方法:

JdkDynamicAopProxy中是通过AopUtils.invokeJoinpointUsingReflection方法来直接调用目标对象的方法,源码如下:

(2).Cglib2AopProxy直接调用目标对象方法:

Cglib2AopProxy是通过methodProxy.invoke来直接调用目标对象的方法,主要源码如下:

methodProxyCGLIBMethodProxy类的对象,因为我对CGLIB也不熟悉,这里不做深入了解。

7.AOP拦截器链的调用:

通过上面45分别对JdkDynamicAopProxyCglib2AopProxy创建AOPProxy代理对象,以及对目标对象的通知器回调我们了解到,当目标对象配置了通知器时,在对目标对象方法调用前首先需要回调通知器链,JdkDynamicAopProxyCglib2AopProxy都是通过将目标对象方法、方法参数、和通知器链、代理对象等封装为ReflectiveMethodInvocation类,然后通过ReflectiveMethodInvocation.proceed()方法调用通知器链,proceed方法源码如下:


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值