天天看点

Spring AOP 代理对象创建流程源码剖析

首先来看一段Spring横切逻辑的配置,这里不去做Spring Aspect使用相关的说明,配置贴出来方便后面Debug流程跟踪时,方便分析

Spring AOP 代理对象创建流程源码剖析

 思考一: 切面编程,Mybatis框架中有使用到过该编程思想(Mapper的动态代理方式)MyBatis Mapper JDK动态代理方式源码分析。Spring中的Aop也一样是通过了动态代理去生成代理对象,那么是使用的常规的实现接口的方式?还是使用的cglib动态代理?

思考二: 之前已经剖析过了Sping IOC容器加载过程的源码,动态代理的对象是另外去加载的还是和流程一样的去加载的?

一,关于代理对象容器初始化完成是否已经创建完成

通过Debug模式可以发现,在容器初始化完成时,testBean就已经创建完成注入到了容器对象。而且通过名称testBean -> {[email protected]} "[email protected]"可以发现这个类是一个cglib动态代理对象。

Spring AOP 代理对象创建流程源码剖析

 二,实例化追踪入口方法

既然对象是在容器初始化完成后就已经完成了创建,那么自然还是和IOC流程初始化时一样,从实例化方法finishBeanFactoryInitialization进入。

具体坐标:AbstractApplicationContext.class refresh方法

Spring AOP 代理对象创建流程源码剖析

 三,代理对象产生入口方法

从finishBeanFactoryInitialization进入,里面的流程之前Spring IOC容器源码剖析中有做过分析了,这里就不全部列举出详细流程了。动态代理的产生,是在被代理对象实例化后然后去产生的代理对象的,是一个后置的步骤。这里跟踪流程到initializeBean方法,即不完全类实例化后属性填充的下一步,进入到该方法中可以看到对应的加载步骤,主要看后置after方法的调用。

具体坐标:AbstractAutowireCapableBeanFactory.class  doCreateBean方法

Spring AOP 代理对象创建流程源码剖析
Spring AOP 代理对象创建流程源码剖析

 四,BeanPostProcessor后置处理方法与代理对象

 之前BeanFactory单例容器中的对象有很多个,这里加一个筛选的条件。在for循环中会发现回家下载一个proxy对象:AbstractAdvisorAutoProxyCreator

Spring AOP 代理对象创建流程源码剖析
Spring AOP 代理对象创建流程源码剖析

继续往下走,会跟踪到AbstractAutoProxyCreator类里面去来到postProcessAfterInstantiation方法,并且最后回进入进入到return的wrapIfNecessary方法中,进去之后一直往下走会进入到createProxy方法中。

具体坐标:AbstractAutoProxyCreator.class

Spring AOP 代理对象创建流程源码剖析
Spring AOP 代理对象创建流程源码剖析
Spring AOP 代理对象创建流程源码剖析

继续往下走,会创建把任务提交给一个代理工厂对象,同时做一个判断,ProxyTargetClass为上面for循环中获取对象时,用红框标记的判断属性与值。继续往下走,做完代理对象创建的准备工作之后就开始创建代理对象。

Spring AOP 代理对象创建流程源码剖析
Spring AOP 代理对象创建流程源码剖析

继续进入,getProxy方法中,首先会先去创建一个AopProxy对象,然后去获取动态代理。

Spring AOP 代理对象创建流程源码剖析

 五,createAopProxy方法

上面的getProxy分两个方法来说明,跟踪进入之后,会获取一个动态代理工厂,显然这里用到了工厂模式。 

Spring AOP 代理对象创建流程源码剖析
Spring AOP 代理对象创建流程源码剖析

 工厂对象获取完成后,继续Debug进入到createAopProxy方法。这个方法中发现SpringAop是有提供JDK动态代理去获取代理对象的,if判断中配置的参数选择了使用什么代理方法。一开始的配置中没有做任何的配置处理所以默认情况下使用的是cglib动态代理。

Spring AOP 代理对象创建流程源码剖析
六,getProxy方法

AopProxy对象获取了之后,就要回到前面的getProxy方法了,这个方法有两个实现类,会代表了两个不同的动态代理对象实现的方式,上面通过debug也可以看到使用的是cglib,那么进入到CglibAopProxy类中,通过断点也可以验证其是否会到该类 ,然后继续往下走到Enhancer对象的创建,到这里为止后面的部分则为Cglib动态代理的使用方式了,不做多的剖析。

Spring AOP 代理对象创建流程源码剖析
Spring AOP 代理对象创建流程源码剖析
Spring AOP 代理对象创建流程源码剖析

到此一个动态代理对象被创建成功并且返回,以上则为Spring Aop代理对象创建的流程源码剖析