【阅读前提】: 需了解
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
执行完成后,进行目标方法,并进行回流执行拦截器的目标方法。
版权归原作者 程序猿进阶 所有, 如有侵权,请联系我们删除。