Spring——AOP之bean标签源码探查
每天进步一点点,大家好,我是大龄码农。
一转眼,2026年的1月已悄然过去,即便是996+的“光辉岁月”,也经不起时间的流逝,慢慢归于黯然与平淡。2月,在这个令人期待的月份,希望大家能享受春节的喜悦和休息日的闲适,也能关注自己的成长。
今天我们聊聊AOP的源码,基于动态代理的实现。在讲解之前,最好先了解以下知识:
-
IoC创建对象的过程
注:以下的分析基于AOP之动态代理实现中的第一种方式:使用bean标签+Spring原生类

以下说明主要分为三部分:
-
第一部分:容器的启动
-
第二部分:获取bean
-
第三部分:执行目标方法
第一部分:容器的启动
在聊循环依赖时,以源码的形式,简单介绍了bean生命周期的整体流程,所以,我们直接从DefaultListableBeanFactory类开始

说明1:对于普通类来说,按照正常步骤创建对象后,放入一级缓存
说明2:因为ProxyFactoryBean实现了FactoryBean接口,所以在处理id为proxy的配置时,要执行isFactoryBean这个分支,其他的大同小异,最后也是放入一级缓存中
说明3:此时name为proxy的value是ProxyFactoryBean对象
第二部分:获取bean
proxy配置的明明是ProxyFactoryBean类,通过getBean()方法获取的对象是BankImpl,这其中到底发生了什么?
我们直接看这部分代码:AbstractBeanFactory#getObjectForBeanInstance(),由于前面的判断都不满足,程序会执行到这里

说明:isSynthetic()方法用于判断是不是内部类,所以此时变量synthetic的值为false,那么方法对应的入参值是true

说明:有没有一种似曾相识的感觉,调用XXX()方法后,再调用doXXX()方法

说明:又是一种似曾相识的感觉,有没有让你想起ObjectFactory

说明:我们来到了ProxyFactoryBean类,从名字上看,这个方法做了两件事:初始化通知链以及获取单例实例
初始化通知链

说明1:从源码上知道了为什么配置interceptorNames属性
说明2:从容器中获取logInCheck的单例对象
说明3:将通知增加到通知链中

说明:转换成通知的对象,加到通知链中
namedBeanToAdvisor

说明:直接进入到包装方法,LogInCheck是Advice的实现类,所以进入到循环中

说明:这个循环就是分别去适配advice对象,满足的话就转换成DefaultPointcutAdvisor对象。大家应该发现了,这是一个责任链模式
前置通知适配器

DefaultPointcutAdvisor类

说明:Pointcut.TRUE是TruePointcut对象

说明:懒汉式的单例模式
addAdvisor()

说明:一路点进去,就会发现使用List<Advisor>维护的通知链
获取单例实例

说明1:获取目标对象,这里就是BankImpl实例
说明2:设置接口,这里就是IBank接口
说明3:创建动态代理
createAopProxy()

说明:AopProxyFactory的实现类是DefaultAopProxyFactory

说明1:根据不同的情况,决定使用Jdk代理还是Cglib代理。
说明2:本例中使用Jdk代理
getProxy(AopProxy)

说明1:底层还是使用的Proxy.newProxyInstance创建代理
说明2:简单看下Cglib代理的实现,使用的是enhancer

好了,此时我们获得了一个代理对象,程序继续向下


说明1:由于FactoryBean创建对象是属于定制化的,所以参考BeanFactory创建对象的流程,对象还需要进行初始化。
说明2:只匹配合适的BeanPostProcessor#postProcessAfterInitialization()方法执行
说明3:此时返回name为proxy的对象是一个代理对象, 它与目标对象实现了相同的接口IBank
第三部分:执行目标方法
返回对象是一个代理对象,使用Jdk的方式代理,所以在调用目标方法时会触发JdkDynamicAopProxy#invoke()方法

说明:这里主要关注这个方法,获取拦截器链

继续进入

说明1:循环通知链,判断对象类型,大家是否还记得前面有个责任链循环进行适配,成功后创建了一个DefaultPointcutAdvisor对象
说明2:与配置的execute表达式相匹配的方法才能被执行增强的方法
说明3:将Advisor转换成MethodInterceptor

说明1:再次出现循环适配
说明2:返回数组的原因是因为可能匹配多个方法。本例只配置了一个。

说明:来到方法下面,包装ReflectiveMethodInvocation类,调用对应的方法

说明:本例中调用的是MethodBeforeAdviceInterceptor类中的方法

说明:此时mi是ReflectiveMethodInvocation对象,递归调用

说明:此处是递归的返回点,即执行切点方法

说明:有兴趣的同学,可以在这个例子的基础上,增加一个AfterReturningAdvice的实现类,看看效果。
特点
不仅能直接获取到目标对象,也能通过代理对象获取到目标对象。
夜雨聆风
