0


Spring AOP 源码分析

【阅读前提】: 需了解

AOP

注解开发流程:链接

一、注解

@EnableAspectJAutoProxy

在配置类中添加注解

@EnableAspectJAutoProxy

,便开启了

AOP

(面向切面编程) 功能。此注解也是了解

AOP

源码的入口。

@EnableAspectJAutoProxy@ConfigurationpublicclassMainConfigOfAOP{

【1】

@EnableAspectJAutoProxy

是什么?我们进入注解,查看其源码如下:发现调用

EnableAspectJAutoProxy

类,同时使用

 @Import

注解向容器中导入

AspectJAutoProxyRegistrar

组件:作用是给容器中注册自定义的

Bean

@Import(AspectJAutoProxyRegistrar.class)public@interfaceEnableAspectJAutoProxy{

【2】进入

AspectJAutoProxyRegistrar

类,调用

registerBeanDefinitions

中的

register...Necessary

方法注册组件。

classAspectJAutoProxyRegistrarimplementsImportBeanDefinitionRegistrar{@OverridepublicvoidregisterBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry){//向容器(registry)中注入组件    AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

【3】 进入

register...Necessary

方法,通过源码分析:该方法向容器中注册一个

AnnotationAwareAspectJAutoProxyCreator

(支持注解模式的面向切面自动代理创建器)组件,其名称为

internalAutoProxyCreator

。需要注意的是其注册的是一个

BeanDefinition

Bean

的定义信息,并没有实例化。后续分析时会说到) 。

//debug 进来后,发现cls参数的值等于 AnnotationAwareAspectJAutoProxyCreator 这个参数也是直接写死的,如下:。//registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);@NullableprivatestaticBeanDefinitionregisterOrEscalateApcAsRequired(Class<?> cls,BeanDefinitionRegistry registry,@NullableObject source){Assert.notNull(registry,"BeanDefinitionRegistry must not be null");//AUTO_PROXY_CREATOR_BEAN_NAME == internalAutoProxyCreator //因第一次进来,所以容器中不存在 internalAutoProxyCreator if(registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)){BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);if(!cls.getName().equals(apcDefinition.getBeanClassName())){int currentPriority =findPriorityForClass(apcDefinition.getBeanClassName());int requiredPriority =findPriorityForClass(cls);if(currentPriority < requiredPriority){
                apcDefinition.setBeanClassName(cls.getName());}}returnnull;}//创建一个新的对象封装 clsRootBeanDefinition beanDefinition =newRootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order",Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);//将封装的cls对象注册到容器中,并将名称定义为AUTO_PROXY_CREATOR_BEAN_NAME == internalAutoProxyCreator 就上上述判断的语句。//此时我们就应该分析 AnnotationAwareAspectJAutoProxyCreator对象的作用
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);return beanDefinition;}

二、研究

AnnotationAwareAspectJAutoProxyCreator

此自动代理创建器的内部功能,其等价于

AOP

的主要功能。 此类的继承结构如下:

我们进入自动代理的抽象父类

AbstractAutoProxyCreator

中发现,其实现了

SmartInstantiationAwareBeanPostProcessor

后置处理器(在

bean

初始化前后做一些操作,

AOP

的特点)和

BeanFactoryAware

自动装配

BeanFactory

@SuppressWarnings("serial")publicabstractclassAbstractAutoProxyCreatorextendsProxyProcessorSupportimplementsSmartInstantiationAwareBeanPostProcessor,BeanFactoryAware{

AOP原理分析技巧:【看给容器中注册了什么组件, 这个组件什么时候工作,这个组件的功能是什么?】,研究透这些,原理也就清楚了。

我们从

AbstractAutoProxyCreator

父类向

AnnotationAwareAspectJAutoProxyCreator

子类的顺序,查看其内部关于后置处理器和自动装备的方法并加入断点:

【1】

AbstractAutoProxyCreator

:包含后置处理器前后的两个方法和自动装配的方法。

//后置处理器相关的方法1@OverridepublicObjectpostProcessBeforeInstantiation(Class<?> beanClass,String beanName){Object cacheKey =getCacheKey(beanClass, beanName);if(!StringUtils.hasLength(beanName)||!this.targetSourcedBeans.contains(beanName)){if(this.advisedBeans.containsKey(cacheKey)){returnnull;}if(isInfrastructureClass(beanClass)||shouldSkip(beanClass, beanName)){this.advisedBeans.put(cacheKey,Boolean.FALSE);returnnull;}}//后置处理器相关的方法2@OverridepublicObjectpostProcessAfterInitialization(@NullableObject bean,String beanName){if(bean !=null){Object cacheKey =getCacheKey(bean.getClass(), beanName);if(this.earlyProxyReferences.remove(cacheKey)!= bean){returnwrapIfNecessary(bean, beanName, cacheKey);}}return bean;}//自动装备相关的方法@OverridepublicvoidsetBeanFactory(BeanFactory beanFactory){this.beanFactory = beanFactory;}

【2】

AbstractAdvisorAutoProxyCreator

:重写了

setBeanFactory

方法。

//自动装备方法@OverridepublicvoidsetBeanFactory(BeanFactory beanFactory){super.setBeanFactory(beanFactory);if(!(beanFactory instanceofConfigurableListableBeanFactory)){thrownewIllegalArgumentException("AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: "+ beanFactory);}initBeanFactory((ConfigurableListableBeanFactory) beanFactory);}

【3】对 2中的

initBeanFactory

方法进行了重写。

@OverrideprotectedvoidinitBeanFactory(ConfigurableListableBeanFactory beanFactory){super.initBeanFactory(beanFactory);if(this.aspectJAdvisorFactory ==null){this.aspectJAdvisorFactory =newReflectiveAspectJAdvisorFactory(beanFactory);}this.aspectJAdvisorsBuilder =newBeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory,this.aspectJAdvisorFactory);}

三、Debug 测试类流程梳理

【1】创建 IOC 容器,传入主配置类

MainConfigOfAOP
//获取容器中的类ApplicationContextApplicationContext=newAnnotationConfigApplicationContext(MainConfigOfAOP.class);

【2】调用

AnnotationConfigApplicationContext

构造器:注册配置类和刷新容器(创建容器中的所有

Bean

,类似于初始化容器)

publicAnnotationConfigApplicationContext(Class<?>... annotatedClasses){//创建对象this();//注册配置类register(annotatedClasses);//刷新容器refresh();}

【3】调用

refresh

方法:主要查看

registerBeanPostProcessors(beanFactory)

; 方法,其作用是注册

bean

后置处理器,用方便来拦截

bean

的创建。

@Overridepublicvoidrefresh()throwsBeansException,IllegalStateException{synchronized(this.startupShutdownMonitor){....// 注册 bean 后置处理器,用来拦截 bean 的创建registerBeanPostProcessors(beanFactory);....}

【4】进入

registerBeanPostProcessors

调用的方法:先获取 IOC 容器中已经定义了的需要创建对象的所有后置处理器

BeanPostProcessor

(已定义:指我们在解析配置类的时候

@EnableAspectJAutoProxy

会为我们注册一个

AnnotationAwareAspectJAutoProxyCreator

后置处理器的定义,包括默认的一些后置处理器的定义)例如:

上述列表中的

internalAutoProxyCreator

后置处理器,就是我们分析

@EnableAspectJAutoProxy

时注入的那个处理器。后置处理的注册分为以下三种情况:
 ■ 优先注册实现了

PriorityOrdered

(优先级)接口的

BeanPostProcessors


 ■ 其次注册实现了

Ordered

接口的

BeanPostProcessors


 ■ 注册所有常规

Beanpstprocessors

internalAutoProxyCreator

后置处理器实现了

Ordered

接口。分析代码可知:【根据

bean

定义名称

internalAutoProxyCreator

beanFactory

中获取注入的后置处理器】调用的方法 =

beanFactory.getBean(ppName, BeanPostProcessor.class)

;

publicstaticvoidregisterBeanPostProcessors(ConfigurableListableBeanFactory beanFactory,AbstractApplicationContext applicationContext){//获取ioc容器中已经定义了的需要创建对象的所有 BeanPostProcessorString[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class,true,false);//也会注意一些其他后置处理器,bean 是在 beanPostProcessor 实例化期间创建的,即 bean 不适合由所有 beanPostProcessors 处理。这个其实不重要,可以省略...int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount()+1+    postProcessorNames.length;
    beanFactory.addBeanPostProcessor(newBeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));//判断哪些后置处理器配置了优先级for(String ppName : postProcessorNames){if(beanFactory.isTypeMatch(ppName,PriorityOrdered.class)){BeanPostProcessor pp = beanFactory.getBean(ppName,BeanPostProcessor.class);
        priorityOrderedPostProcessors.add(pp);if(pp instanceofMergedBeanDefinitionPostProcessor){
            internalPostProcessors.add(pp);}}elseif(beanFactory.isTypeMatch(ppName,Ordered.class)){
        orderedPostProcessorNames.add(ppName);}else{
        nonOrderedPostProcessorNames.add(ppName);}}// 优先注册实现了 PriorityOrdered(优先级) 的 BeanPostProcessorssortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// 其次注册实现了Ordered 接口的 BeanPostProcessors.List<BeanPostProcessor> orderedPostProcessors =newArrayList<>();for(String ppName : orderedPostProcessorNames){//根据 bean定义的名称internalAutoProxyCreator 从 beanFactory 中获取注入的后置处理器BeanPostProcessor pp = beanFactory.getBean(ppName,BeanPostProcessor.class);
    orderedPostProcessors.add(pp);if(pp instanceofMergedBeanDefinitionPostProcessor){
        internalPostProcessors.add(pp);}}sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, orderedPostProcessors);// 注册所有常规beanpstprocessors。List<BeanPostProcessor> nonOrderedPostProcessors =newArrayList<>();for(String ppName : nonOrderedPostProcessorNames){BeanPostProcessor pp = beanFactory.getBean(ppName,BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);if(pp instanceofMergedBeanDefinitionPostProcessor){
            internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// 最后,重新注册所有内部beanpstprocessors。sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);

【5】进入上述所说的

beanFactory.getBean(ppName, BeanPostProcessor.class)

; 方法如下:因第一次进入容器,因此获取不到实例。会通过

getSingleton

方法创建

BeanPostProcessor

的实例,并保存到容器中。

@Overridepublic<T>TgetBean(String name,Class<T> requiredType)throwsBeansException{returndoGetBean(name, requiredType,null,false);}//上述方法内部调用的是 doGetBean(name, requiredType, null, false); 代码如下:@SuppressWarnings("unchecked")protected<T>TdoGetBean(finalString name,@NullablefinalClass<T> requiredType,@NullablefinalObject[] args,boolean typeCheckOnly)throwsBeansException{//因为第一次获取,容器中不存在此实例。因此 sharedInstance==nullObject sharedInstance =getSingleton(beanName);if(sharedInstance !=null&& args ==null){...}else{// 创建 bean 实例if(mbd.isSingleton()){
            sharedInstance =getSingleton(beanName,()->{try{returncreateBean(beanName, mbd, args);}catch(BeansException ex){destroySingleton(beanName);throw ex;}});
        bean =getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}}

【6】创建

internalAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator

实例。步骤如下:

//1、创建bean的实例createBean(beanName, mbd, args);//2、给Bean 的各属性赋值populateBean(beanName, mbd, instanceWrapper);//3、初始化 bean ,比较重要,因为后置处理器就是在此前后进行工作的
exposedObject =initializeBean(beanName, exposedObject, mbd);

【7】重点是:初始化

initializeBean

方法,查看实现的步骤如下:

//1、调用 invokeAwareMethods 处理Aware 接口的方法回调,beanName=internalAutoProxyCreator 实现了 BeanAware 接口invokeAwareMethods(beanName, bean);//2、应用后置处理器 BeforeInitializationapplyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);//3、执行自定义的初始化方法invokeInitMethods(beanName, wrappedBean, mbd);//4、执行后置处理器的 After方法applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//下面是上述方法的具体实现//1、invokeAwareMethods 实现如下:privatevoidinvokeAwareMethods(finalString beanName,finalObject bean){if(bean instanceofAware){//.....//实现了 BeanFactoryAware 接口,因此执行 setBeanFactory.//bean==AnnotationAwareAspectJAutoProxyCreatorif(bean instanceofBeanFactoryAware){((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}//2、applyBeanPostProcessorsBeforeInitialization 实现如下:@OverridepublicObjectapplyBeanPostProcessorsBeforeInitialization(Object existingBean,String beanName)throwsBeansException{Object result = existingBean;//获取所有的后置处理器,执行前置Before 处理器。for(BeanPostProcessor processor :getBeanPostProcessors()){Object current = processor.postProcessBeforeInitialization(result, beanName);if(current ==null){return result;}
        result = current;}return result;}//3、invokeInitMethods 方法的具体实现protectedvoidinvokeInitMethods(String beanName,finalObject bean,@NullableRootBeanDefinition mbd)throwsThrowable{boolean isInitializingBean =(bean instanceofInitializingBean);if(isInitializingBean &&(mbd ==null||!mbd.isExternallyManagedInitMethod("afterPropertiesSet"))){if(logger.isTraceEnabled()){
            logger.trace("Invoking afterPropertiesSet() on bean with name '"+ beanName +"'");}if(System.getSecurityManager()!=null){try{AccessController.doPrivileged((PrivilegedExceptionAction<Object>)()->{((InitializingBean) bean).afterPropertiesSet();returnnull;},getAccessControlContext());}catch(PrivilegedActionException pae){throw pae.getException();}}else{((InitializingBean) bean).afterPropertiesSet();}}if(mbd !=null&& bean.getClass()!=NullBean.class){String initMethodName = mbd.getInitMethodName();if(StringUtils.hasLength(initMethodName)&&!(isInitializingBean &&"afterPropertiesSet".equals(initMethodName))&&!mbd.isExternallyManagedInitMethod(initMethodName)){invokeCustomInitMethod(beanName, bean, mbd);}}}//4、applyBeanPostProcessorsAfterInitialization 具体实现@OverridepublicObjectapplyBeanPostProcessorsAfterInitialization(Object existingBean,String beanName)throwsBeansException{Object result = existingBean;for(BeanPostProcessor processor :getBeanPostProcessors()){Object current = processor.postProcessAfterInitialization(result, beanName);if(current ==null){return result;}
        result = current;}return result;}

【8】执行

Aware

初始化时,会调用

setBeanFactory

方法,我们追下去会发现调用的是

AbstractAdvisorAutoProxyCreator

setBeanFactory

方法(就是我们分析

AnnotationAwareAspectJAutoProxyCreator

继承关系时的父类 )。

AnnotationAwareAspectJAutoProxyCreator(AbstractAdvisorAutoProxyCreator).setBeanFactory(BeanFactory)line:58
@OverridepublicvoidsetBeanFactory(BeanFactory beanFactory){//调用父类的 setBeanFactorysuper.setBeanFactory(beanFactory);if(!(beanFactory instanceofConfigurableListableBeanFactory)){thrownewIllegalArgumentException("AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: "+ beanFactory);}//AnnotationAwareAspectJAutoProxyCreator  方法对此进行了重写initBeanFactory((ConfigurableListableBeanFactory) beanFactory);}

【9】进入

initBeanFactory

方法,我们知道此方法已被

AnnotationAwareAspectJAutoProxyCreator

重写:

//位于 AnnotationAwareAspectJAutoProxyCreator 类中@OverrideprotectedvoidinitBeanFactory(ConfigurableListableBeanFactory beanFactory){super.initBeanFactory(beanFactory);if(this.aspectJAdvisorFactory ==null){//创建了放射的通知工厂this.aspectJAdvisorFactory =newReflectiveAspectJAdvisorFactory(beanFactory);}this.aspectJAdvisorsBuilder =newBeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory,this.aspectJAdvisorFactory);}

【10】最终

BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)

创建成功,将其添加到

beanFactory

中。

for(String ppName : orderedPostProcessorNames){//实例 pp==AnnotationAwareAspectJAutoProxyCreator BeanPostProcessor pp = beanFactory.getBean(ppName,BeanPostProcessor.class);//放入 ordered后置处理器集合
    orderedPostProcessors.add(pp);if(pp instanceofMergedBeanDefinitionPostProcessor){
        internalPostProcessors.add(pp);}}//将处理器按优先级排序sortPostProcessors(orderedPostProcessors, beanFactory);//调用注册方法registerBeanPostProcessors(beanFactory, orderedPostProcessors);//上述注册方法的内部代码privatestaticvoidregisterBeanPostProcessors(ConfigurableListableBeanFactory beanFactory,List<BeanPostProcessor> postProcessors){//将后置处理器都添加到bean工厂for(BeanPostProcessor postProcessor : postProcessors){
        beanFactory.addBeanPostProcessor(postProcessor);}}

四、后置处理器创建后的操作

【1】以上是创建和注册

AnnotationAwareAspectJAutoProxyCreator

的过程。接下来就是对创建后的流程进行说明:

AnnotationAwareAspectJAutoProxyCreator

是继承

InstantiationAwareBeanPostProcessor

的后置处理器:我们在上面说的

IOC

容器初始化时,会调用

refresh

方法:我们进入此方法看下,我们之前分析

registerBeanPostProcessors

方法,接下来分析

finishBeanFactoryInitialization

方法(实例所有剩余的单实例

bean

)完成

BeanFactory

初始化工作。

@Overridepublicvoidrefresh()throwsBeansException,IllegalStateException{synchronized(this.startupShutdownMonitor){//......// 注册 bean后置处理器 来拦截 bean 的创建。registerBeanPostProcessors(beanFactory);//......// 初始化特定上下文子类中的其他特殊bean。onRefresh();//......// 实例化所有剩余的(非延迟初始化)单例。finishBeanFactoryInitialization(beanFactory);}

【2】遍历获取容器中所有的

Bean

,依次创建对象

getBean(beanName)

; 流程:

getBean

->

doGetBean()

->

getSingleton()

getBean

方法如下:先从缓存中获取当前

bean

,如果能获取到说明

bean

是之前被创建过的,直接使用,否则创建

bean

;只要是创建好的

bean

都会被缓存起来。

// 先检查单例缓存中是否有已存在手动注册的单例,如果存在说明之前bean已创建Object sharedInstance =getSingleton(beanName);//缓存中不存在 bean 时才创建该单例 beanif(sharedInstance !=null&& args ==null){//...}else{//创建bean实例。if(mbd.isSingleton()){
        sharedInstance =getSingleton(beanName,()->{try{returncreateBean(beanName, mbd, args);}catch(BeansException ex){destroySingleton(beanName);throw ex;}});
        bean =getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}}

【2.1】进入创建

bean

的步骤:

createBean

方法,首先会调用

resolveBeforeInstantiation

方法,让

beanPostProcessors

后置处理器有机会返回代理对象而不是目标

bean

实例。如果能返回则直接使用,如果不能则调用

doCreateBean

方法来创建实例。

@OverrideprotectedObjectcreateBean(String beanName,RootBeanDefinition mbd,@NullableObject[] args)throwsBeanCreationException{/*现获取类的基本信息 例如:
        Root bean: class [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]; 
        scope=singleton等等*/RootBeanDefinition mbdToUse = mbd;//......//让beanPostProcessors有机会返回代理而不是目标bean实例。        Object bean =resolveBeforeInstantiation(beanName, mbdToUse);if(bean !=null){return bean;}//通过此方法,先调用 aware、前置处理器、bean初始化、后置处理器 ,之前有分析过。Object beanInstance =doCreateBean(beanName, mbdToUse, args);}

BeanPostProcessor

是在

Bean

对象创建完成初始化前后调用的】

InstantiationAwareBeanPostProcessor

是在创建

bean

实例之前先尝试用后置处理器返回代理对象】
后置处理器与后置处理器不同,具体什么时候调用,需要根据不同情况而定。

【2.1.1】分析

resolveBeforeInstantiation

方法(让

beanPostProcessors

有机会返回代理对象):我们分析的

AnnotationAwareAspectJAutoProxyCreator

就是

InstantiationAwareBeanPostProcessor

类型的后置处理器。会在任何

bean

创建之前先尝试返回

bean

的代理实例。

@NullableprotectedObjectresolveBeforeInstantiation(String beanName,RootBeanDefinition mbd){
    bean =applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if(bean !=null){
        bean =applyBeanPostProcessorsAfterInitialization(bean, beanName);}}//上面两个方法的源码展示@NullableprotectedObjectapplyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass,String beanName){//获取所有的后置处理器for(BeanPostProcessor bp :getBeanPostProcessors()){//如果后置处理器是 InstantiationAwareBeanPostProcessor 类型的处理器则执行 postProcessBeforeInstantiation 方法。//我们分析的 AnnotationAwareAspectJAutoProxyCreator 就是 InstantiationAwareBeanPostProcessor 类型的处理器if(bp instanceofInstantiationAwareBeanPostProcessor){InstantiationAwareBeanPostProcessor ibp =(InstantiationAwareBeanPostProcessor) bp;//***** 后续分析Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);if(result !=null){return result;}}}returnnull;}

【2.1.1.1】接着分析上述的

postProcessBeforeInstantiation

方法:内容较多,放在五中分析。

【2.1.2】分析

doCreateBean

方法,之前有介绍过,我们在看下源码:就是对创建的目标类前后对后置处理器的方法进行初始化。才是真正创建一个

bean

的实例。

protectedObjectdoCreateBean(finalString beanName,finalRootBeanDefinition mbd,final@NullableObject[] args)throwsBeanCreationException{//创建 bean 实例
    instanceWrapper =createBeanInstance(beanName, mbd, args);//bean 属性赋值populateBean(beanName, mbd, instanceWrapper);//初始化 bean
    exposedObject =initializeBean(beanName, exposedObject, mbd);}//初始化方法 initializeBean 的源码protectedObjectinitializeBean(finalString beanName,finalObject bean,@NullableRootBeanDefinition mbd){//初始化 aware 接口的类invokeAwareMethods(beanName, bean);//后置处理器 Before 方法初始化
    wrappedBean =applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);//初始化类invokeInitMethods(beanName, wrappedBean, mbd);//后置处理器 after 方法初始化
    wrappedBean =applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//返回创建好的类return wrappedBean;}

五、

postProcessBeforeInstantiation

方法分析

【1】每个

bean

创建之前,调用此方法。我们主要观察业务逻辑

MathCalculator

类和切面

LogAspects

类的创建。

//当bean = MathCalculator or LogAspects 我们着重分析此方法,其他的略过@OverridepublicObjectpostProcessBeforeInstantiation(Class<?> beanClass,String beanName){Object cacheKey =getCacheKey(beanClass, beanName);if(!StringUtils.hasLength(beanName)||!this.targetSourcedBeans.contains(beanName)){//判断当前 bean 是否在 advisedBeans 中(保存了所有需要增加的 bean:意思就是添加了切面的内容),第一次进行肯定是不包含的所以会跳过if(this.advisedBeans.containsKey(cacheKey)){returnnull;}//isInfrastructureClass 判断当前类是否为基础类型的,也就是实现了 Advice、Pointcut、Advisor、AopInfrastructureBean //或者是否为切面注解标注的类 (@Aspect),第一个 MathCalculator = false//shouldSkip 是否需要跳过:内部是获取候选的增强器(也就是切面内的通知方法)//将所有的增强器封装成了 List<Advisor> 集合,增强器的类型是 InstantiationModelAwarePointcutAdvisorif(isInfrastructureClass(beanClass)||shouldSkip(beanClass, beanName)){this.advisedBeans.put(cacheKey,Boolean.FALSE);returnnull;}}// targetSource = nullTargetSource targetSource =getCustomTargetSource(beanClass, beanName);if(targetSource !=null){if(StringUtils.hasLength(beanName)){this.targetSourcedBeans.add(beanName);}Object[] specificInterceptors =getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);Object proxy =createProxy(beanClass, beanName, specificInterceptors, targetSource);this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}//直接返回空,进入我们配置类中,创建 MathCalculator 对象returnnull;}

【2】上述代码中的

shouldSkip

源码:

@OverrideprotectedbooleanshouldSkip(Class<?> beanClass,String beanName){//获取所有的增强器 考虑通过缓存方面名称列表进行优化List<Advisor> candidateAdvisors =findCandidateAdvisors();for(Advisor advisor : candidateAdvisors){//我们的增强器都是 InstantiationModelAwarePointcutAdvisor 类型的,不是AspectJPointcutAdvisor 所以跳过if(advisor instanceofAspectJPointcutAdvisor&&((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)){returntrue;}}//父类直接返回 falsereturnsuper.shouldSkip(beanClass, beanName);}

【3】创建完

MathCalculator

后,调用

postProcessAfterInitialization
@OverridepublicObjectpostProcessAfterInitialization(@NullableObject bean,String beanName){if(bean !=null){// cacheKey = calculatorObject cacheKey =getCacheKey(bean.getClass(), beanName);//判断之前是否代理过if(this.earlyProxyReferences.remove(cacheKey)!= bean){//包装目标类,如果需要的话returnwrapIfNecessary(bean, beanName, cacheKey);}}return bean;}

【3.1】查看包装方法

wrapIfNecessary

的源码:分析后得出如下结论:以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程

protectedObjectwrapIfNecessary(Object bean,String beanName,Object cacheKey){//...... 省略的都是判断是否为切面类或以代理类//如果需要就创建代理类//getAdvicesAndAdvisorsForBean 获取能在当前类使用的增强器Object[] specificInterceptors =getAdvicesAndAdvisorsForBean(bean.getClass(), beanName,null);if(specificInterceptors !=DO_NOT_PROXY){//保存当前 bean 在advisedBeans 表示当前bean 被处理了this.advisedBeans.put(cacheKey,Boolean.TRUE);//创建代理对象 ****重点,返回的是一个通过 Cglib 代理的对象Object proxy =createProxy(
        bean.getClass(), beanName, specificInterceptors,newSingletonTargetSource(bean));this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}this.advisedBeans.put(cacheKey,Boolean.FALSE);return bean;

【3.1.1】进入当前类使用的增强器方法:

getAdvicesAndAdvisorsForBean
@Override@NullableprotectedObject[]getAdvicesAndAdvisorsForBean(Class<?> beanClass,String beanName,@NullableTargetSource targetSource){//获取可用的增强器List<Advisor> advisors =findEligibleAdvisors(beanClass, beanName);if(advisors.isEmpty()){returnDO_NOT_PROXY;}return advisors.toArray();}

【3.1.1.1】进入获取可用增强器的方法:

findEligibleAdvisors
protectedList<Advisor>findEligibleAdvisors(Class<?> beanClass,String beanName){//获取后置增强器List<Advisor> candidateAdvisors =findCandidateAdvisors();//找到能在当前bean中使用的增强器(找那些方法能够切入到当前方法的)List<Advisor> eligibleAdvisors =findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);extendAdvisors(eligibleAdvisors);if(!eligibleAdvisors.isEmpty()){//对增强器进行了排序
        eligibleAdvisors =sortAdvisors(eligibleAdvisors);}return eligibleAdvisors;}//上面获取当前bean中使用的增强器的方法源码protectedList<Advisor>findAdvisorsThatCanApply(List<Advisor> candidateAdvisors,Class<?> beanClass,String beanName){ProxyCreationContext.setCurrentProxiedBeanName(beanName);try{//通过 AopUtils工具类获取所有的通知方法returnAopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);}finally{ProxyCreationContext.setCurrentProxiedBeanName(null);}}//工具类方法源码展示publicstaticList<Advisor>findAdvisorsThatCanApply(List<Advisor> candidateAdvisors,Class<?> clazz){if(candidateAdvisors.isEmpty()){return candidateAdvisors;}List<Advisor> eligibleAdvisors =newArrayList<>();for(Advisor candidate : candidateAdvisors){//我们的增强器不是此类型if(candidate instanceofIntroductionAdvisor&&canApply(candidate, clazz)){
            eligibleAdvisors.add(candidate);}}boolean hasIntroductions =!eligibleAdvisors.isEmpty();for(Advisor candidate : candidateAdvisors){if(candidate instanceofIntroductionAdvisor){// already processedcontinue;}//判断增强器是否可用,我们的都是可用的if(canApply(candidate, clazz, hasIntroductions)){//将所有可以使用的增强器,加入到可用的增强器集合中
            eligibleAdvisors.add(candidate);}}return eligibleAdvisors;}//判断是否为可用的增强器的方法 canApply源码:publicstaticbooleancanApply(Advisor advisor,Class<?> targetClass,boolean hasIntroductions){if(advisor instanceofIntroductionAdvisor){return((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);}//查看切面的方法是否都能匹配elseif(advisor instanceofPointcutAdvisor){PointcutAdvisor pca =(PointcutAdvisor) advisor;returncanApply(pca.getPointcut(), targetClass, hasIntroductions);}else{// It doesn't have a pointcut so we assume it applies.returntrue;}}

【3.1.2】进入代理对象的创建方法:

createProxy
protectedObjectcreateProxy(Class<?> beanClass,@NullableString beanName,@NullableObject[] specificInterceptors,TargetSource targetSource){if(this.beanFactory instanceofConfigurableListableBeanFactory){AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);}//创建代理工厂ProxyFactory proxyFactory =newProxyFactory();
    proxyFactory.copyFrom(this);if(!proxyFactory.isProxyTargetClass()){if(shouldProxyTargetClass(beanClass, beanName)){
            proxyFactory.setProxyTargetClass(true);}else{evaluateProxyInterfaces(beanClass, proxyFactory);}}//获取所有的增强器,并保存在代理工厂Advisor[] advisors =buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);if(advisorsPreFiltered()){
        proxyFactory.setPreFiltered(true);}//使用代理工厂创建对象return proxyFactory.getProxy(getProxyClassLoader());}

【3.1.2.1】进入代理工厂创建对象的方法

proxyFactory.getProxy

的源码:

publicObjectgetProxy(@NullableClassLoader classLoader){returncreateAopProxy().getProxy(classLoader);}//进入 createAopProxy().getProxy 内部的内部方法@OverridepublicAopProxycreateAopProxy(AdvisedSupport config)throwsAopConfigException{if(config.isOptimize()|| config.isProxyTargetClass()||hasNoUserSuppliedProxyInterfaces(config)){Class<?> targetClass = config.getTargetClass();if(targetClass ==null){thrownewAopConfigException("TargetSource cannot determine target class: "+"Either an interface or a target is required for proxy creation.");}//创建 JDK 代理或者 Cglib 代理。如果实现了接口则使用 JDK 代理,否则Cglib 代理if(targetClass.isInterface()||Proxy.isProxyClass(targetClass)){returnnewJdkDynamicAopProxy(config);}returnnewObjenesisCglibAopProxy(config);}else{returnnewJdkDynamicAopProxy(config);}}

六、目标方法执行

【1】容器中保存了组件的代理对象(

cglib

增强后的对象),这个对象里面保存了详细信息(比如:增强器,目标对象…)

【2】

CglibAopProxy.intercept()

; 拦截目标方法执行如下:主要是根据

ProxyFactory

对象获取将要执行的目标方法的拦截器链。
 1)、如果没有拦截器链,直接执行目标方法。
 2)、如果有拦截器链,吧需要执行的目标对象,目标方法,拦截器链等信息传入创建一个

CglibMethodInvocation

对象,并调用

retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed()

; 方法。

@Override@NullablepublicObjectintercept(Object proxy,Method method,Object[] args,MethodProxy methodProxy)throwsThrowable{Object oldProxy =null;boolean setProxyContext =false;Object target =null;TargetSource targetSource =this.advised.getTargetSource();try{if(this.advised.exposeProxy){
            oldProxy =AopContext.setCurrentProxy(proxy);
            setProxyContext =true;}
        target = targetSource.getTarget();Class<?> targetClass =(target !=null? target.getClass():null);//根据 ProxyFactory 对象获取将要执行的目标方法的拦截器链List<Object> chain =this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);Object retVal;//如果没有拦截器链,直接执行目标方法。if(chain.isEmpty()&&Modifier.isPublic(method.getModifiers())){Object[] argsToUse =AopProxyUtils.adaptArgumentsIfNecessary(method, args);
            retVal = methodProxy.invoke(target, argsToUse);}//如果有拦截器链,吧需要执行的目标对象,目标方法,拦截器链等信息传入创建一个 CglibMethodInvocation 对象,并调用如下方法。else{
            retVal =newCglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}
        retVal =processReturnType(proxy, target, method, retVal);return retVal;}finally{//......}}

【3】 拦截器链:

List<Object> chain = advised.getInterceptorsAndDynamicInterceptionAdvice

的源码展示:
 1)、

List<Object> interceptorList

中保存了所有拦截器,总计5个。一个默认的

ExposeInvocationInterceptor

和 4个增强器。
 2)、遍历所有的增强器,将其转为

Interceptor

(拦截器):

registry.getInterceptors(advisor)

;

@OverridepublicList<Object>getInterceptorsAndDynamicInterceptionAdvice(Advised config,Method method,@NullableClass<?> targetClass){//......//获取所有的增强器进行遍历for(Advisor advisor : advisors){//判断是否为切面的增强器if(advisor instanceofPointcutAdvisor){//......//将增强器转化为 MethodInterceptorMethodInterceptor[] interceptors = registry.getInterceptors(advisor);if(mm.isRuntime()){for(MethodInterceptor interceptor : interceptors){
                    interceptorList.add(newInterceptorAndDynamicMethodMatcher(interceptor, mm));}}else{
                interceptorList.addAll(Arrays.asList(interceptors));}}elseif(advisor instanceofIntroductionAdvisor){IntroductionAdvisor ia =(IntroductionAdvisor) advisor;if(config.isPreFiltered()|| ia.getClassFilter().matches(actualClass)){Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));}}else{Interceptor[] interceptors = registry.getInterceptors(advisor);
            interceptorList.addAll(Arrays.asList(interceptors));}}return interceptorList;}

 3)、将增强器转为

MethodInterceptor

,转化方式如下:最终返回拦截器链(每一个通知方法又被包装为方法拦截器,后期都是利用

MethodInterceptor

机制)。

@OverridepublicMethodInterceptor[]getInterceptors(Advisor advisor)throwsUnknownAdviceTypeException{List<MethodInterceptor> interceptors =newArrayList<>(3);Advice advice = advisor.getAdvice();//如果是 MethodInterceptor 直接加入到 list 中if(advice instanceofMethodInterceptor){
        interceptors.add((MethodInterceptor) advice);}//如果不是则,使用 AdvisorAdapter 将增强器转为 MethodInterceptorfor(AdvisorAdapter adapter :this.adapters){if(adapter.supportsAdvice(advice)){
            interceptors.add(adapter.getInterceptor(advisor));}}if(interceptors.isEmpty()){thrownewUnknownAdviceTypeException(advisor.getAdvice());}return interceptors.toArray(newMethodInterceptor[0]);}

【4】拦截器链有了之后,创建

CglibMethodInvocation

并执行

proceed

方法:

retVal =newCglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

七、拦截器链的触发过程

【1】拦截器链展示:除了默认的方法

ExposeInvocationInterceptor

剩下的 4个都是我们切面中的方法。

【2】如果没有拦截器执行目标方法执行代理对象

CglibMethodInvocation

proceed

方法:

retVal =newCglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

【3】进入

proceed

方法:

@Override@NullablepublicObjectproceed()throwsThrowable{//判断连接器栏的长度是否 == 0,此方法会在拦截器链的最后一个链时调用if(this.currentInterceptorIndex ==this.interceptorsAndDynamicMethodMatchers.size()-1){//执行目标方式,输入为:MathCalculator...div...returninvokeJoinpoint();}//获取下标=0的拦截器 ExposeInvocationInterceptorObject interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);if(interceptorOrInterceptionAdvice instanceofInterceptorAndDynamicMethodMatcher){//下标0 跳过......}else{// this=ReflectiveMethodInvocationreturn((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}

【4】进入[

MethodInterceptor

]

interceptorOrInterceptionAdvice

)

.invoke(this)

; 方法:会循环调用

list

中的拦截器,直到后置处理器:

AspectJMethodBeforeAdvice
//ThreadLocal 线程共享数据 (共享 MethodInvocation)privatestaticfinalThreadLocal<MethodInvocation> invocation =newNamedThreadLocal<>("Current AOP method invocation");@OverridepublicObjectinvoke(MethodInvocation mi)throwsThrowable{//获取 invocation MethodInvocation oldInvocation = invocation.get();//将当前方法,放入 invocation
    invocation.set(mi);try{//执行 cglib 的proceed() 就获取到了下标为1的拦截器 AspectJAfterThrowingAdvicereturn mi.proceed();}finally{//执行后置通知
        invocation.set(oldInvocation);}}

【5】 当

advice

=

AspectJMethodBeforeAdvice

后置处理器时,

invoke

方法如下:

@OverridepublicObjectinvoke(MethodInvocation mi)throwsThrowable{//执行后置处理器的 before 方法//输出如下:div运行。。。@Before:参数列表是:{[2, 3]}this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());//进入上述展示的 processd 方法,此时进入第一个判断语句,执行目标方法return mi.proceed();}

【6】 后置处理器的

After

方法执行的

invoke

方法展示:最终执行结果的返回方法。

@OverridepublicObjectinvoke(MethodInvocation mi)throwsThrowable{try{return mi.proceed();}finally{//执行 after 方法:div结束。。。@AfterinvokeAdviceMethod(getJoinPointMatch(),null,null);}}

【7】上述分析的流程图如下:根据链表循环向下执行,当最后一个后置处理器的

before

执行完成后,进行目标方法,并进行回流执行拦截器的目标方法。

标签: spring java 后端

本文转载自: https://blog.csdn.net/zhengzhaoyang122/article/details/135612257
版权归原作者 程序猿进阶 所有, 如有侵权,请联系我们删除。

“Spring AOP 源码分析”的评论:

还没有评论