这一次搞懂Spring代理创建及AOP链式调用过程操作
前言
AOP,也就是面向切面编程,它可以将公共的代码抽离出来,动态的织入到目标类、目标方法中,大大提高我们编程的效率,也使程序变得更加优雅。如事务、操作日志等都可以使用AOP实现。这种织入可以是在运行期动态生成代理对象实现,也可以在编译期、类加载时期静态织入到代码中。而Spring正是通过第一种方法实现,且在代理类的生成上也有两种方式:JDKProxy和CGLIB,默认当类实现了接口时使用前者,否则使用后者;另外SpringAOP只能实现对方法的增强。
正文
基本概念
AOP的术语很多,虽然不清楚术语我们也能很熟练地使用AOP,但是要理解分析源码,术语就需要深刻体会其含义。
增强(Advice):就是我们想要额外增加的功能
目标对象(Target):就是我们想要增强的目标类,如果没有AOP,我们需要在每个目标对象中实现日志、事务管理等非业务逻辑
连接点(JoinPoint):程序执行时的特定时机,如方法执行前、后以及抛出异常后等等。
切点(Pointcut):连接点的导航,我们如何找到目标对象呢?切点的作用就在于此,在Spring中就是匹配表达式。
引介(Introduction):引介是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过AOP的引介功能,我们可以动态地为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。
织入(Weaving):即如何将增强添加到目标对象的连接点上,有动态(运行期生成代理)、静态(编译期、类加载时期)两种方式。
代理(Proxy):目标对象被织入增强后,就会产生一个代理对象,该对象可能是和原对象实现了同样的一个接口(JDK),也可能是原对象的子类(CGLIB)。
切面(Aspect、Advisor):切面由切点和增强组成,包含了这两者的定义。
代理对象的创建
在熟悉了AOP术语后,下面就来看看Spring是如何创建代理对象的,是否还记得上一篇提到的AOP的入口呢?在AbstractAutowireCapableBeanFactory类的applyBeanPostProcessorsAfterInitialization方法中循环调用了BeanPostProcessor的postProcessAfterInitialization方法,其中一个就是我们创建代理对象的入口。
这里是Bean实例化完成去创建代理对象,理所当然应该这样,但实际上在Bean实例化之前调用了一个resolveBeforeInstantiation方法,这里实际上我们也是有机会可以提前创建代理对象的,这里放到最后来分析,先来看主入口,进入到AbstractAutoProxyCreator类中:
publicObjectpostProcessAfterInitialization(@NullableObjectbean,StringbeanName){
if(bean!=null){
ObjectcacheKey=getCacheKey(bean.getClass(),beanName);
if(!this.earlyProxyReferences.contains(cacheKey)){
returnwrapIfNecessary(bean,beanName,cacheKey);
}
}
returnbean;
}
protectedObjectwrapIfNecessary(Objectbean,StringbeanName,ObjectcacheKey){
//创建当前bean的代理,如果这个bean有advice的话,重点看
//Createproxyifwehaveadvice.
Object[]specificInterceptors=getAdvicesAndAdvisorsForBean(bean.getClass(),beanName,null);
//如果有切面,则生成该bean的代理
if(specificInterceptors!=DO_NOT_PROXY){
this.advisedBeans.put(cacheKey,Boolean.TRUE);
//把被代理对象bean实例封装到SingletonTargetSource对象中
Objectproxy=createProxy(
bean.getClass(),beanName,specificInterceptors,newSingletonTargetSource(bean));
this.proxyTypes.put(cacheKey,proxy.getClass());
returnproxy;
}
this.advisedBeans.put(cacheKey,Boolean.FALSE);
returnbean;
}
先从缓存中拿,没有则调用wrapIfNecessary方法创建。在这个方法里面主要看两个地方:getAdvicesAndAdvisorsForBean和createProxy。简单一句话概括就是先扫描后创建,问题是扫描什么呢?你可以先结合上面的概念思考下,换你会怎么做。进入到子类AbstractAdvisorAutoProxyCreator的getAdvicesAndAdvisorsForBean方法中:
protectedObject[]getAdvicesAndAdvisorsForBean(
Class>beanClass,StringbeanName,@NullableTargetSourcetargetSource){
//找到合格的切面
Listadvisors=findEligibleAdvisors(beanClass,beanName);
if(advisors.isEmpty()){
returnDO_NOT_PROXY;
}
returnadvisors.toArray();
}
protectedListfindEligibleAdvisors(Class>beanClass,StringbeanName){
//找到候选的切面,其实就是一个寻找有@Aspectj注解的过程,把工程中所有有这个注解的类封装成Advisor返回
ListcandidateAdvisors=findCandidateAdvisors();
//判断候选的切面是否作用在当前beanClass上面,就是一个匹配过程。现在就是一个匹配
ListeligibleAdvisors=findAdvisorsThatCanApply(candidateAdvisors,beanClass,beanName);
extendAdvisors(eligibleAdvisors);
if(!eligibleAdvisors.isEmpty()){
//对有@Order@Priority进行排序
eligibleAdvisors=sortAdvisors(eligibleAdvisors);
}
returneligibleAdvisors;
}
    
在findEligibleAdvisors方法中可以看到有两个步骤,第一先找到所有的切面,即扫描所有带有@Aspect注解的类,并将其中的切点(表达式)和增强封装为切面,扫描完成后,自然是要判断哪些切面能够连接到当前Bean实例上。下面一步步来分析,首先是扫描过程,进入到AnnotationAwareAspectJAutoProxyCreator类中:
protectedListfindCandidateAdvisors(){ //先通过父类AbstractAdvisorAutoProxyCreator扫描,这里不重要 List advisors=super.findCandidateAdvisors(); //主要看这里 if(this.aspectJAdvisorsBuilder!=null){ advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } returnadvisors; } 
这里委托给了BeanFactoryAspectJAdvisorsBuilderAdapter类,并调用其父类的buildAspectJAdvisors方法创建切面对象:
publicListbuildAspectJAdvisors(){ List aspectNames=this.aspectBeanNames; if(aspectNames==null){ synchronized(this){ aspectNames=this.aspectBeanNames; if(aspectNames==null){ List advisors=newArrayList<>(); aspectNames=newArrayList<>(); //获取spring容器中的所有bean的名称BeanName String[]beanNames=BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory,Object.class,true,false); for(StringbeanName:beanNames){ if(!isEligibleBean(beanName)){ continue; } Class>beanType=this.beanFactory.getType(beanName); if(beanType==null){ continue; } //判断类上是否有@Aspect注解 if(this.advisorFactory.isAspect(beanType)){ aspectNames.add(beanName); AspectMetadataamd=newAspectMetadata(beanType,beanName); if(amd.getAjType().getPerClause().getKind()==PerClauseKind.SINGLETON){ //当@Aspect的value属性为""时才会进入到这里 //创建获取有@Aspect注解类的实例工厂,负责获取有@Aspect注解类的实例 MetadataAwareAspectInstanceFactoryfactory= newBeanFactoryAspectInstanceFactory(this.beanFactory,beanName); //创建切面advisor对象 List classAdvisors=this.advisorFactory.getAdvisors(factory); if(this.beanFactory.isSingleton(beanName)){ this.advisorsCache.put(beanName,classAdvisors); } else{ this.aspectFactoryCache.put(beanName,factory); } advisors.addAll(classAdvisors); } else{ MetadataAwareAspectInstanceFactoryfactory= newPrototypeAspectInstanceFactory(this.beanFactory,beanName); this.aspectFactoryCache.put(beanName,factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } this.aspectBeanNames=aspectNames; returnadvisors; } } } returnadvisors; } 
这个方法里面首先从IOC中拿到所有Bean的名称,并循环判断该类上是否带有@Aspect注解,如果有则将BeanName和Bean的Class类型封装到BeanFactoryAspectInstanceFactory中,并调用ReflectiveAspectJAdvisorFactory.getAdvisors创建切面对象:
publicListgetAdvisors(MetadataAwareAspectInstanceFactoryaspectInstanceFactory){ //从工厂中获取有@Aspect注解的类Class Class>aspectClass=aspectInstanceFactory.getAspectMetadata().getAspectClass(); //从工厂中获取有@Aspect注解的类的名称 StringaspectName=aspectInstanceFactory.getAspectMetadata().getAspectName(); validate(aspectClass); //创建工厂的装饰类,获取实例只会获取一次 MetadataAwareAspectInstanceFactorylazySingletonAspectInstanceFactory= newLazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List advisors=newArrayList<>(); //这里循环没有@Pointcut注解的方法 for(Methodmethod:getAdvisorMethods(aspectClass)){ //非常重要重点看看 Advisoradvisor=getAdvisor(method,lazySingletonAspectInstanceFactory,advisors.size(),aspectName); if(advisor!=null){ advisors.add(advisor); } } if(!advisors.isEmpty()&&lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()){ AdvisorinstantiationAdvisor=newSyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0,instantiationAdvisor); } //判断属性上是否有引介注解,这里可以不看 for(Fieldfield:aspectClass.getDeclaredFields()){ //判断属性上是否有DeclareParents注解,如果有返回切面 Advisoradvisor=getDeclareParentsAdvisor(field); if(advisor!=null){ advisors.add(advisor); } } returnadvisors; } privateList getAdvisorMethods(Class>aspectClass){ finalList methods=newArrayList<>(); ReflectionUtils.doWithMethods(aspectClass,method->{ //Excludepointcuts if(AnnotationUtils.getAnnotation(method,Pointcut.class)==null){ methods.add(method); } }); methods.sort(METHOD_COMPARATOR); returnmethods; } 
根据Aspect的Class拿到所有不带@Pointcut注解的方法对象(为什么是不带@Pointcut注解的方法?仔细想想不难理解),另外要注意这里对method进行了排序,看看这个METHOD_COMPARATOR比较器:
privatestaticfinalComparatorMETHOD_COMPARATOR; static{ Comparator adviceKindComparator=newConvertingComparator<>( newInstanceComparator<>( Around.class,Before.class,After.class,AfterReturning.class,AfterThrowing.class), (Converter )method->{ AspectJAnnotation>annotation= AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method); return(annotation!=null?annotation.getAnnotation():null); }); Comparator methodNameComparator=newConvertingComparator<>(Method::getName); METHOD_COMPARATOR=adviceKindComparator.thenComparing(methodNameComparator); } 
关注InstanceComparator构造函数参数,记住它们的顺序,这就是AOP链式调用中同一个@Aspect类中Advice的执行顺序。接着往下看,在getAdvisors方法中循环获取到的methods,分别调用getAdvisor方法,也就是根据方法逐个去创建切面:
publicAdvisorgetAdvisor(MethodcandidateAdviceMethod,MetadataAwareAspectInstanceFactoryaspectInstanceFactory,
intdeclarationOrderInAspect,StringaspectName){
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//获取pointCut对象,最重要的是从注解中获取表达式
AspectJExpressionPointcutexpressionPointcut=getPointcut(
candidateAdviceMethod,aspectInstanceFactory.getAspectMetadata().getAspectClass());
if(expressionPointcut==null){
returnnull;
}
//创建Advisor切面类,这才是真正的切面类,一个切面类里面肯定要有1、pointCut2、advice
//这里pointCut是expressionPointcut,advice增强方法是candidateAdviceMethod
returnnewInstantiationModelAwarePointcutAdvisorImpl(expressionPointcut,candidateAdviceMethod,
this,aspectInstanceFactory,declarationOrderInAspect,aspectName);
}
privatestaticfinalClass>[]ASPECTJ_ANNOTATION_CLASSES=newClass>[]{
Pointcut.class,Around.class,Before.class,After.class,AfterReturning.class,AfterThrowing.class};
privateAspectJExpressionPointcutgetPointcut(MethodcandidateAdviceMethod,Class>candidateAspectClass){
//从候选的增强方法里面candidateAdviceMethod找有有注解
//Pointcut.class,Around.class,Before.class,After.class,AfterReturning.class,AfterThrowing.class
//并把注解信息封装成AspectJAnnotation对象
AspectJAnnotation>aspectJAnnotation=
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if(aspectJAnnotation==null){
returnnull;
}
//创建一个PointCut类,并且把前面从注解里面解析的表达式设置进去
AspectJExpressionPointcutajexp=
newAspectJExpressionPointcut(candidateAspectClass,newString[0],newClass>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if(this.beanFactory!=null){
ajexp.setBeanFactory(this.beanFactory);
}
returnajexp;
}
之前就说过切面的定义,是切点和增强的组合,所以这里首先通过getPointcut获取到注解对象,然后new了一个Pointcut对象,并将表达式设置进去。然后在getAdvisor方法中最后new了一个InstantiationModelAwarePointcutAdvisorImpl对象:
publicInstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcutdeclaredPointcut,
MethodaspectJAdviceMethod,AspectJAdvisorFactoryaspectJAdvisorFactory,
MetadataAwareAspectInstanceFactoryaspectInstanceFactory,intdeclarationOrder,StringaspectName){
this.declaredPointcut=declaredPointcut;
this.declaringClass=aspectJAdviceMethod.getDeclaringClass();
this.methodName=aspectJAdviceMethod.getName();
this.parameterTypes=aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod=aspectJAdviceMethod;
this.aspectJAdvisorFactory=aspectJAdvisorFactory;
this.aspectInstanceFactory=aspectInstanceFactory;
this.declarationOrder=declarationOrder;
this.aspectName=aspectName;
if(aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()){
//Staticpartofthepointcutisalazytype.
PointcutpreInstantiationPointcut=Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(),this.declaredPointcut);
//Makeitdynamic:mustmutatefrompre-instantiationtopost-instantiationstate.
//Ifit'snotadynamicpointcut,itmaybeoptimizedout
//bytheSpringAOPinfrastructureafterthefirstevaluation.
this.pointcut=newPerTargetInstantiationModelPointcut(
this.declaredPointcut,preInstantiationPointcut,aspectInstanceFactory);
this.lazy=true;
}
else{
//Asingletonaspect.
this.pointcut=this.declaredPointcut;
this.lazy=false;
//这个方法重点看看,创建advice对象
this.instantiatedAdvice=instantiateAdvice(this.declaredPointcut);
}
}
这个就是我们的切面类,在其构造方法的最后通过instantiateAdvice创建了Advice对象。注意这里传进来的declarationOrder参数,它就是循环method时的序号,其作用就是赋值给这里的declarationOrder属性以及Advice的declarationOrder属性,在后面排序时就会通过这个序号来比较,因此Advice的执行顺序是固定的,至于为什么要固定,后面分析完AOP链式调用过程自然就明白了。
publicAdvicegetAdvice(MethodcandidateAdviceMethod,AspectJExpressionPointcutexpressionPointcut,
MetadataAwareAspectInstanceFactoryaspectInstanceFactory,intdeclarationOrder,StringaspectName){
//获取有@Aspect注解的类
Class>candidateAspectClass=aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
//找到candidateAdviceMethod方法上面的注解,并且包装成AspectJAnnotation对象,这个对象中就有注解类型
AspectJAnnotation>aspectJAnnotation=
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if(aspectJAnnotation==null){
returnnull;
}
AbstractAspectJAdvicespringAdvice;
//根据不同的注解类型创建不同的advice类实例
switch(aspectJAnnotation.getAnnotationType()){
caseAtPointcut:
if(logger.isDebugEnabled()){
logger.debug("Processingpointcut'"+candidateAdviceMethod.getName()+"'");
}
returnnull;
caseAtAround:
//实现了MethodInterceptor接口
springAdvice=newAspectJAroundAdvice(
candidateAdviceMethod,expressionPointcut,aspectInstanceFactory);
break;
caseAtBefore:
//实现了MethodBeforeAdvice接口,没有实现MethodInterceptor接口
springAdvice=newAspectJMethodBeforeAdvice(
candidateAdviceMethod,expressionPointcut,aspectInstanceFactory);
break;
caseAtAfter:
//实现了MethodInterceptor接口
springAdvice=newAspectJAfterAdvice(
candidateAdviceMethod,expressionPointcut,aspectInstanceFactory);
break;
caseAtAfterReturning:
//实现了AfterReturningAdvice接口,没有实现MethodInterceptor接口
springAdvice=newAspectJAfterReturningAdvice(
candidateAdviceMethod,expressionPointcut,aspectInstanceFactory);
AfterReturningafterReturningAnnotation=(AfterReturning)aspectJAnnotation.getAnnotation();
if(StringUtils.hasText(afterReturningAnnotation.returning())){
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
caseAtAfterThrowing:
//实现了MethodInterceptor接口
springAdvice=newAspectJAfterThrowingAdvice(
candidateAdviceMethod,expressionPointcut,aspectInstanceFactory);
AfterThrowingafterThrowingAnnotation=(AfterThrowing)aspectJAnnotation.getAnnotation();
if(StringUtils.hasText(afterThrowingAnnotation.throwing())){
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
thrownewUnsupportedOperationException(
"Unsupportedadvicetypeonmethod:"+candidateAdviceMethod);
}
//Nowtoconfiguretheadvice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[]argNames=this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if(argNames!=null){
springAdvice.setArgumentNamesFromStringArray(argNames);
}
//计算argNames和类型的对应关系
springAdvice.calculateArgumentBindings();
returnspringAdvice;
}
这里逻辑很清晰,就是拿到方法上的注解类型,根据类型创建不同的增强Advice对象:AspectJAroundAdvice、AspectJMethodBeforeAdvice、AspectJAfterAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice。完成之后通过calculateArgumentBindings方法进行参数绑定,感兴趣的可自行研究。这里主要看看几个Advice的继承体系:
可以看到有两个Advice是没有实现MethodInterceptor接口的:AspectJMethodBeforeAdvice和AspectJAfterReturningAdvice。而MethodInterceptor有一个invoke方法,这个方法就是链式调用的核心方法,但那两个没有实现该方法的Advice怎么处理呢?稍后会分析。
到这里切面对象就创建完成了,接下来就是判断当前创建的Bean实例是否和这些切面匹配以及对切面排序。匹配过程比较复杂,对理解主流程也没什么帮助,所以这里就不展开分析,感兴趣的自行分析(AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply())。
下面看看排序的过程,回到AbstractAdvisorAutoProxyCreator.findEligibleAdvisors方法:
protectedListfindEligibleAdvisors(Class>beanClass,StringbeanName){ //找到候选的切面,其实就是一个寻找有@Aspectj注解的过程,把工程中所有有这个注解的类封装成Advisor返回 List candidateAdvisors=findCandidateAdvisors(); //判断候选的切面是否作用在当前beanClass上面,就是一个匹配过程。。现在就是一个匹配 List eligibleAdvisors=findAdvisorsThatCanApply(candidateAdvisors,beanClass,beanName); extendAdvisors(eligibleAdvisors); if(!eligibleAdvisors.isEmpty()){ //对有@Order@Priority进行排序 eligibleAdvisors=sortAdvisors(eligibleAdvisors); } returneligibleAdvisors; } 
sortAdvisors方法就是排序,但这个方法有两个实现:当前类AbstractAdvisorAutoProxyCreator和子类AspectJAwareAdvisorAutoProxyCreator,应该走哪个呢?
通过类图我们可以肯定是进入的AspectJAwareAdvisorAutoProxyCreator类,因为AnnotationAwareAspectJAutoProxyCreator的父类是它。
protectedListsortAdvisors(List advisors){ List partiallyComparableAdvisors=newArrayList<>(advisors.size()); for(Advisorelement:advisors){ partiallyComparableAdvisors.add( newPartiallyComparableAdvisorHolder(element,DEFAULT_PRECEDENCE_COMPARATOR)); } List sorted=PartialOrder.sort(partiallyComparableAdvisors); if(sorted!=null){ List result=newArrayList<>(advisors.size()); for(PartiallyComparableAdvisorHolderpcAdvisor:sorted){ result.add(pcAdvisor.getAdvisor()); } returnresult; } else{ returnsuper.sortAdvisors(advisors); } } 
这里排序主要是委托给PartialOrder进行的,而在此之前将所有的切面都封装成了PartiallyComparableAdvisorHolder对象,注意传入的DEFAULT_PRECEDENCE_COMPARATOR参数,这个就是比较器对象:
privatestaticfinalComparator
DEFAULT_PRECEDENCE_COMPARATOR=newAspectJPrecedenceComparator(); 
所以我们直接看这个比较器的compare方法:
publicintcompare(Advisoro1,Advisoro2){
intadvisorPrecedence=this.advisorComparator.compare(o1,o2);
if(advisorPrecedence==SAME_PRECEDENCE&&declaredInSameAspect(o1,o2)){
advisorPrecedence=comparePrecedenceWithinAspect(o1,o2);
}
returnadvisorPrecedence;
}
privatefinalComparatoradvisorComparator;
publicAspectJPrecedenceComparator(){
this.advisorComparator=AnnotationAwareOrderComparator.INSTANCE;
}
第一步先通过AnnotationAwareOrderComparator去比较,点进去看可以发现是对实现了PriorityOrdered和Ordered接口以及标记了Priority和Order注解的非同一个@Aspect类中的切面进行排序。这个和之前分析BeanFacotryPostProcessor类是一样的原理。而对同一个@Aspect类中的切面排序主要是comparePrecedenceWithinAspect方法:
privateintcomparePrecedenceWithinAspect(Advisoradvisor1,Advisoradvisor2){
booleanoneOrOtherIsAfterAdvice=
(AspectJAopUtils.isAfterAdvice(advisor1)||AspectJAopUtils.isAfterAdvice(advisor2));
intadviceDeclarationOrderDelta=getAspectDeclarationOrder(advisor1)-getAspectDeclarationOrder(advisor2);
if(oneOrOtherIsAfterAdvice){
//theadvicedeclaredlasthashigherprecedence
if(adviceDeclarationOrderDelta<0){
//advice1wasdeclaredbeforeadvice2
//soadvice1haslowerprecedence
returnLOWER_PRECEDENCE;
}
elseif(adviceDeclarationOrderDelta==0){
returnSAME_PRECEDENCE;
}
else{
returnHIGHER_PRECEDENCE;
}
}
else{
//theadvicedeclaredfirsthashigherprecedence
if(adviceDeclarationOrderDelta<0){
//advice1wasdeclaredbeforeadvice2
//soadvice1hashigherprecedence
returnHIGHER_PRECEDENCE;
}
elseif(adviceDeclarationOrderDelta==0){
returnSAME_PRECEDENCE;
}
else{
returnLOWER_PRECEDENCE;
}
}
}
privateintgetAspectDeclarationOrder(AdvisoranAdvisor){
AspectJPrecedenceInformationprecedenceInfo=
AspectJAopUtils.getAspectJPrecedenceInformationFor(anAdvisor);
if(precedenceInfo!=null){
returnprecedenceInfo.getDeclarationOrder();
}
else{
return0;
}
}
这里就是通过precedenceInfo.getDeclarationOrder拿到在创建InstantiationModelAwarePointcutAdvisorImpl对象时设置的declarationOrder属性,这就验证了之前的说法(实际上这里排序过程非常复杂,不是简单的按照这个属性进行排序)。
当上面的一切都进行完成后,就该创建代理对象了,回到AbstractAutoProxyCreator.wrapIfNecessary,看关键部分代码:
//如果有切面,则生成该bean的代理
if(specificInterceptors!=DO_NOT_PROXY){
this.advisedBeans.put(cacheKey,Boolean.TRUE);
//把被代理对象bean实例封装到SingletonTargetSource对象中
Objectproxy=createProxy(
bean.getClass(),beanName,specificInterceptors,newSingletonTargetSource(bean));
this.proxyTypes.put(cacheKey,proxy.getClass());
returnproxy;
}
注意这里将被代理对象封装成了一个SingletonTargetSource对象,它是TargetSource的实现类。
protectedObjectcreateProxy(Class>beanClass,@NullableStringbeanName,
@NullableObject[]specificInterceptors,TargetSourcetargetSource){
if(this.beanFactoryinstanceofConfigurableListableBeanFactory){
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory,beanName,beanClass);
}
//创建代理工厂
ProxyFactoryproxyFactory=newProxyFactory();
proxyFactory.copyFrom(this);
if(!proxyFactory.isProxyTargetClass()){
if(shouldProxyTargetClass(beanClass,beanName)){
//proxyTargetClass是否对类进行代理,而不是对接口进行代理,设置为true时,使用CGLib代理。
proxyFactory.setProxyTargetClass(true);
}
else{
evaluateProxyInterfaces(beanClass,proxyFactory);
}
}
//把advice类型的增强包装成advisor切面
Advisor[]advisors=buildAdvisors(beanName,specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
用来控制代理工厂被配置后,是否还允许修改代理的配置,默认为false
proxyFactory.setFrozen(this.freezeProxy);
if(advisorsPreFiltered()){
proxyFactory.setPreFiltered(true);
}
//获取代理实例
returnproxyFactory.getProxy(getProxyClassLoader());
}
这里通过ProxyFactory对象去创建代理实例,这是工厂模式的体现,但在创建代理对象之前还有几个准备动作:需要判断是JDK代理还是CGLIB代理以及通过buildAdvisors方法将扩展的Advice封装成Advisor切面。准备完成则通过getProxy创建代理对象:
publicObjectgetProxy(@NullableClassLoaderclassLoader){
//根据目标对象是否有接口来判断采用什么代理方式,cglib代理还是jdk动态代理
returncreateAopProxy().getProxy(classLoader);
}
protectedfinalsynchronizedAopProxycreateAopProxy(){
if(!this.active){
activate();
}
returngetAopProxyFactory().createAopProxy(this);
}
publicAopProxycreateAopProxy(AdvisedSupportconfig)throwsAopConfigException{
if(config.isOptimize()||config.isProxyTargetClass()||hasNoUserSuppliedProxyInterfaces(config)){
Class>targetClass=config.getTargetClass();
if(targetClass==null){
thrownewAopConfigException("TargetSourcecannotdeterminetargetclass:"+
"Eitheraninterfaceoratargetisrequiredforproxycreation.");
}
if(targetClass.isInterface()||Proxy.isProxyClass(targetClass)){
returnnewJdkDynamicAopProxy(config);
}
returnnewObjenesisCglibAopProxy(config);
}
else{
returnnewJdkDynamicAopProxy(config);
}
}
首先通过配置拿到对应的代理类:ObjenesisCglibAopProxy和JdkDynamicAopProxy,然后再通过getProxy创建Bean的代理,这里以JdkDynamicAopProxy为例:
publicObjectgetProxy(@NullableClassLoaderclassLoader){
//advised是代理工厂对象
Class>[]proxiedInterfaces=AopProxyUtils.completeProxiedInterfaces(this.advised,true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
returnProxy.newProxyInstance(classLoader,proxiedInterfaces,this);
}
这里的代码你应该不陌生了,就是JDK的原生API,newProxyInstance方法传入的InvocationHandler对象是this,因此,最终AOP代理的调用就是从该类中的invoke方法开始。至此,代理对象的创建就完成了,下面来看下整个过程的时序图:
小结
代理对象的创建过程整体来说并不复杂,首先找到所有带有@Aspect注解的类,并获取其中没有@Pointcut注解的方法,循环创建切面,而创建切面需要切点和增强两个元素,其中切点可简单理解为我们写的表达式,增强则是根据@Before、@Around、@After等注解创建的对应的Advice类。切面创建好后则需要循环判断哪些切面能对当前的Bean实例的方法进行增强并排序,最后通过ProxyFactory创建代理对象。
AOP链式调用
熟悉JDK动态代理的都知道通过代理对象调用方法时,会进入到InvocationHandler对象的invoke方法,所以我们直接从JdkDynamicAopProxy的这个方法开始:
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
MethodInvocationinvocation;
ObjectoldProxy=null;
booleansetProxyContext=false;
//从代理工厂中拿到TargetSource对象,该对象包装了被代理实例bean
TargetSourcetargetSource=this.advised.targetSource;
Objecttarget=null;
try{
//被代理对象的equals方法和hashCode方法是不能被代理的,不会走切面
.......
ObjectretVal;
//可以从当前线程中拿到代理对象
if(this.advised.exposeProxy){
//Makeinvocationavailableifnecessary.
oldProxy=AopContext.setCurrentProxy(proxy);
setProxyContext=true;
}
//这个target就是被代理实例
target=targetSource.getTarget();
Class>targetClass=(target!=null?target.getClass():null);
//从代理工厂中拿过滤器链Object是一个MethodInterceptor类型的对象,其实就是一个advice对象
List
这段代码比较长,我删掉了不关键的地方。首先来看this.advised.exposeProxy这个属性,这在@EnableAspectJAutoProxy注解中可以配置,当为true时,会将该代理对象设置到当前线程的ThreadLocal对象中,这样就可以通过AopContext.currentProxy拿到代理对象。这个有什么用呢?我相信有经验的Java开发都遇到过这样一个BUG,在Service实现类中调用本类中的另一个方法时,事务不会生效,这是因为直接通过this调用就不会调用到代理对象的方法,而是原对象的,所以事务切面就没有生效。因此这种情况下就可以从当前线程的ThreadLocal对象拿到代理对象,不过实际上直接使用@Autowired注入自己本身也可以拿到代理对象。
接下来就是通过getInterceptorsAndDynamicInterceptionAdvice拿到执行链,看看具体做了哪些事情:
publicList
这也是个长方法,看关键的部分,因为之前我们创建的基本上都是InstantiationModelAwarePointcutAdvisorImpl对象,该类是PointcutAdvisor的实现类,所以会进入第一个if判断里,这里首先进行匹配,看切点和当前对象以及该对象的哪些方法匹配,如果能匹配上,则调用getInterceptors获取执行链:
privatefinalListadapters=newArrayList<>(3); publicDefaultAdvisorAdapterRegistry(){ registerAdvisorAdapter(newMethodBeforeAdviceAdapter()); registerAdvisorAdapter(newAfterReturningAdviceAdapter()); registerAdvisorAdapter(newThrowsAdviceAdapter()); } publicMethodInterceptor[]getInterceptors(Advisoradvisor)throwsUnknownAdviceTypeException{ List interceptors=newArrayList<>(3); Adviceadvice=advisor.getAdvice(); //如果是MethodInterceptor类型的,如:AspectJAroundAdvice //AspectJAfterAdvice //AspectJAfterThrowingAdvice if(adviceinstanceofMethodInterceptor){ interceptors.add((MethodInterceptor)advice); } //处理AspectJMethodBeforeAdviceAspectJAfterReturningAdvice for(AdvisorAdapteradapter:this.adapters){ if(adapter.supportsAdvice(advice)){ interceptors.add(adapter.getInterceptor(advisor)); } } if(interceptors.isEmpty()){ thrownewUnknownAdviceTypeException(advisor.getAdvice()); } returninterceptors.toArray(newMethodInterceptor[0]); } 
这里我们可以看到如果是MethodInterceptor的实现类,则直接添加到链中,如果不是,则需要通过适配器去包装后添加,刚好这里有MethodBeforeAdviceAdapter和AfterReturningAdviceAdapter两个适配器对应上文两个没有实现MethodInterceptor接口的类。最后将Interceptors返回。
if(chain.isEmpty()){
Object[]argsToUse=AopProxyUtils.adaptArgumentsIfNecessary(method,args);
retVal=AopUtils.invokeJoinpointUsingReflection(target,method,argsToUse);
}
else{
//Weneedtocreateamethodinvocation...
invocation=newReflectiveMethodInvocation(proxy,target,method,args,targetClass,chain);
//Proceedtothejoinpointthroughtheinterceptorchain.
retVal=invocation.proceed();
}
返回到invoke方法后,如果执行链为空,说明该方法不需要被增强,所以直接反射调用原对象的方法(注意传入的是TargetSource封装的被代理对象);反之,则通过ReflectiveMethodInvocation类进行链式调用,关键方法就是proceed:
privateintcurrentInterceptorIndex=-1;
publicObjectproceed()throwsThrowable{
//如果执行链中的advice全部执行完,则直接调用joinPoint方法,就是被代理方法
if(this.currentInterceptorIndex==this.interceptorsAndDynamicMethodMatchers.size()-1){
returninvokeJoinpoint();
}
ObjectinterceptorOrInterceptionAdvice=
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if(interceptorOrInterceptionAdviceinstanceofInterceptorAndDynamicMethodMatcher){
InterceptorAndDynamicMethodMatcherdm=
(InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
Class>targetClass=(this.targetClass!=null?this.targetClass:this.method.getDeclaringClass());
if(dm.methodMatcher.matches(this.method,targetClass,this.arguments)){
returndm.interceptor.invoke(this);
}
else{
returnproceed();
}
}
else{
//调用MethodInterceptor中的invoke方法
return((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
这个方法的核心就在两个地方:invokeJoinpoint和interceptorOrInterceptionAdvice.invoke(this)。当增强方法调用完后就会通过前者调用到被代理的方法,否则则是依次调用Interceptor的invoke方法。下面就分别看看每个Interceptor是怎么实现的。
AspectJAroundAdvice
publicObjectinvoke(MethodInvocationmi)throwsThrowable{
if(!(miinstanceofProxyMethodInvocation)){
thrownewIllegalStateException("MethodInvocationisnotaSpringProxyMethodInvocation:"+mi);
}
ProxyMethodInvocationpmi=(ProxyMethodInvocation)mi;
ProceedingJoinPointpjp=lazyGetProceedingJoinPoint(pmi);
JoinPointMatchjpm=getJoinPointMatch(pmi);
returninvokeAdviceMethod(pjp,jpm,null,null);
}
MethodBeforeAdviceInterceptor->AspectJMethodBeforeAdvice
publicObjectinvoke(MethodInvocationmi)throwsThrowable{
this.advice.before(mi.getMethod(),mi.getArguments(),mi.getThis());
returnmi.proceed();
}
publicvoidbefore(Methodmethod,Object[]args,@NullableObjecttarget)throwsThrowable{
invokeAdviceMethod(getJoinPointMatch(),null,null);
}
AspectJAfterAdvice
publicObjectinvoke(MethodInvocationmi)throwsThrowable{
try{
returnmi.proceed();
}
finally{
invokeAdviceMethod(getJoinPointMatch(),null,null);
}
}
AfterReturningAdviceInterceptor->AspectJAfterReturningAdvice
publicObjectinvoke(MethodInvocationmi)throwsThrowable{
ObjectretVal=mi.proceed();
this.advice.afterReturning(retVal,mi.getMethod(),mi.getArguments(),mi.getThis());
returnretVal;
}
publicvoidafterReturning(@NullableObjectreturnValue,Methodmethod,Object[]args,@NullableObjecttarget)throwsThrowable{
if(shouldInvokeOnReturnValueOf(method,returnValue)){
invokeAdviceMethod(getJoinPointMatch(),returnValue,null);
}
}
AspectJAfterThrowingAdvice
publicObjectinvoke(MethodInvocationmi)throwsThrowable{
try{
returnmi.proceed();
}
catch(Throwableex){
if(shouldInvokeOnThrowing(ex)){
invokeAdviceMethod(getJoinPointMatch(),null,ex);
}
throwex;
}
}
这里的调用顺序是怎样的呢?其核心就是通过proceed方法控制流程,每执行完一个Advice就会回到proceed方法中调用下一个Advice。可以思考一下,怎么才能让调用结果满足如下图的执行顺序。
以上就是AOP的链式调用过程,但是这只是只有一个切面类的情况,如果有多个@Aspect类呢,这个调用过程又是怎样的?其核心思想和“栈”一样,就是“先进后出,后进先出”。
AOP扩展知识
一、自定义全局拦截器Interceptor
在上文创建代理对象的时候有这样一个方法:
protectedAdvisor[]buildAdvisors(@NullableStringbeanName,@NullableObject[]specificInterceptors){
//自定义MethodInterceptor.拿到setInterceptorNames方法注入的Interceptor对象
Advisor[]commonInterceptors=resolveInterceptorNames();
ListallInterceptors=newArrayList<>();
if(specificInterceptors!=null){
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if(commonInterceptors.length>0){
if(this.applyCommonInterceptorsFirst){
allInterceptors.addAll(0,Arrays.asList(commonInterceptors));
}
else{
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
Advisor[]advisors=newAdvisor[allInterceptors.size()];
for(inti=0;i
这个方法的作用就在于我们可以扩展我们自己的Interceptor,首先通过resolveInterceptorNames方法获取到通过setInterceptorNames方法设置的Interceptor,然后调用DefaultAdvisorAdapterRegistry.wrap方法将其包装为DefaultPointcutAdvisor对象并返回:
publicAdvisorwrap(ObjectadviceObject)throwsUnknownAdviceTypeException{
if(adviceObjectinstanceofAdvisor){
return(Advisor)adviceObject;
}
if(!(adviceObjectinstanceofAdvice)){
thrownewUnknownAdviceTypeException(adviceObject);
}
Adviceadvice=(Advice)adviceObject;
if(adviceinstanceofMethodInterceptor){
returnnewDefaultPointcutAdvisor(advice);
}
for(AdvisorAdapteradapter:this.adapters){
if(adapter.supportsAdvice(advice)){
returnnewDefaultPointcutAdvisor(advice);
}
}
thrownewUnknownAdviceTypeException(advice);
}
publicDefaultPointcutAdvisor(Adviceadvice){
this(Pointcut.TRUE,advice);
}
需要注意DefaultPointcutAdvisor构造器里面传入了一个Pointcut.TRUE,表示这种扩展的Interceptor是全局的拦截器。下面来看看如何使用:
publicclassMyMethodInterceptorimplementsMethodInterceptor{
@Override
publicObjectinvoke(MethodInvocationinvocation)throwsThrowable{
System.out.println("自定义拦截器");
returninvocation.proceed();
}
}
首先写一个类实现MethodInterceptor接口,在invoke方法中实现我们的拦截逻辑,然后通过下面的方式测试,只要UserService有AOP拦截就会发现自定义的MyMethodInterceptor也生效了。
publicvoidcostomInterceptorTest(){
AnnotationAwareAspectJAutoProxyCreatorbean=applicationContext.getBean(AnnotationAwareAspectJAutoProxyCreator.class);
bean.setInterceptorNames("myMethodInterceptor");
UserServiceuserService=applicationContext.getBean(UserService.class);
userService.queryUser("dark");
}
但是如果换个顺序,像下面这样:
publicvoidcostomInterceptorTest(){
UserServiceuserService=applicationContext.getBean(UserService.class);
AnnotationAwareAspectJAutoProxyCreatorbean=applicationContext.getBean(AnnotationAwareAspectJAutoProxyCreator.class);
bean.setInterceptorNames("myMethodInterceptor");
userService.queryUser("dark");
}
这时自定义的全局拦截器就没有作用了,这是为什么呢?因为当执行getBean的时候,如果有切面匹配就会通过ProxyFactory去创建代理对象,注意Interceptor是存到这个Factory对象中的,而这个对象和代理对象是一一对应的,因此调用getBean时,还没有myMethodInterceptor这个对象,自定义拦截器就没有效果了,也就是说要想自定义拦截器生效,就必须在代理对象生成之前注册进去。
二、循环依赖三级缓存存在的必要性
在上一篇文章我分析了Spring是如何通过三级缓存来解决循环依赖的问题的,但你是否考虑过第三级缓存为什么要存在?我直接将bean存到二级不就行了么,为什么还要存一个ObjectFactory对象到第三级缓存中?一个是因为不是每个Bean都会出现循环依赖,所以三级缓存只存了一个工厂对象;二是我们在@Autowired对象时,想要注入的不一定是Bean本身,而是想要注入一个修改过后的对象,如代理对象。在AbstractAutowireCapableBeanFactory.getEarlyBeanReference方法中循环调用了SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference方法,AbstractAutoProxyCreator对象就实现了该方法:
publicObjectgetEarlyBeanReference(Objectbean,StringbeanName){
ObjectcacheKey=getCacheKey(bean.getClass(),beanName);
if(!this.earlyProxyReferences.contains(cacheKey)){
this.earlyProxyReferences.add(cacheKey);
}
//创建代理对象
returnwrapIfNecessary(bean,beanName,cacheKey);
}
因此,当我们想要对循坏依赖的Bean做出修改时,就可以像AOP这样做。
三、如何在Bean创建之前提前创建代理对象
Spring的代理对象基本上都是在Bean实例化完成之后创建的,但在文章开始我就说过,Spring也提供了一个机会在创建Bean对象之前就创建代理对象,在AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation方法中:
protectedObjectresolveBeforeInstantiation(StringbeanName,RootBeanDefinitionmbd){
Objectbean=null;
if(!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)){
//Makesurebeanclassisactuallyresolvedatthispoint.
if(!mbd.isSynthetic()&&hasInstantiationAwareBeanPostProcessors()){
Class>targetType=determineTargetType(beanName,mbd);
if(targetType!=null){
bean=applyBeanPostProcessorsBeforeInstantiation(targetType,beanName);
if(bean!=null){
bean=applyBeanPostProcessorsAfterInitialization(bean,beanName);
}
}
}
mbd.beforeInstantiationResolved=(bean!=null);
}
returnbean;
}
protectedObjectapplyBeanPostProcessorsBeforeInstantiation(Class>beanClass,StringbeanName){
for(BeanPostProcessorbp:getBeanPostProcessors()){
if(bpinstanceofInstantiationAwareBeanPostProcessor){
InstantiationAwareBeanPostProcessoribp=(InstantiationAwareBeanPostProcessor)bp;
Objectresult=ibp.postProcessBeforeInstantiation(beanClass,beanName);
if(result!=null){
returnresult;
}
}
}
returnnull;
}
主要是InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法中,这里又会进入到AbstractAutoProxyCreator类中:
publicObjectpostProcessBeforeInstantiation(Class>beanClass,StringbeanName){
TargetSourcetargetSource=getCustomTargetSource(beanClass,beanName);
if(targetSource!=null){
if(StringUtils.hasLength(beanName)){
this.targetSourcedBeans.add(beanName);
}
Object[]specificInterceptors=getAdvicesAndAdvisorsForBean(beanClass,beanName,targetSource);
Objectproxy=createProxy(beanClass,beanName,specificInterceptors,targetSource);
this.proxyTypes.put(cacheKey,proxy.getClass());
returnproxy;
}
returnnull;
}
protectedTargetSourcegetCustomTargetSource(Class>beanClass,StringbeanName){
//Wecan'tcreatefancytargetsourcesfordirectlyregisteredsingletons.
if(this.customTargetSourceCreators!=null&&
this.beanFactory!=null&&this.beanFactory.containsBean(beanName)){
for(TargetSourceCreatortsc:this.customTargetSourceCreators){
TargetSourcets=tsc.getTargetSource(beanClass,beanName);
if(ts!=null){
returnts;
}
}
}
//NocustomTargetSourcefound.
returnnull;
}
看到这里大致应该明白了,先是获取到一个自定义的TargetSource对象,然后创建代理对象,所以我们首先需要自己实现一个TargetSource类,这里直接继承一个抽象类,getTarget方法则返回原始对象:
publicclassMyTargetSourceextendsAbstractBeanFactoryBasedTargetSource{
@Override
publicObjectgetTarget()throwsException{
returngetBeanFactory().getBean(getTargetBeanName());
}
}
但这还不够,上面首先判断了customTargetSourceCreators!=null,而这个属性是个数组,可以通过下面这个方法设置进来:
publicvoidsetCustomTargetSourceCreators(TargetSourceCreator...targetSourceCreators){
this.customTargetSourceCreators=targetSourceCreators;
}
所以我们还要实现一个TargetSourceCreator类,同样继承一个抽象类实现,并只对userServiceImpl对象进行拦截:
publicclassMyTargetSourceCreatorextendsAbstractBeanFactoryBasedTargetSourceCreator{
@Override
protectedAbstractBeanFactoryBasedTargetSourcecreateBeanFactoryBasedTargetSource(Class>beanClass,StringbeanName){
if(getBeanFactory()instanceofConfigurableListableBeanFactory){
if(beanName.equalsIgnoreCase("userServiceImpl")){
returnnewMyTargetSource();
}
}
returnnull;
}
}
createBeanFactoryBasedTargetSource方法是在AbstractBeanFactoryBasedTargetSourceCreator.getTargetSource中调用的,而getTargetSource就是在上面getCustomTargetSource中调用的。以上工作做完后,还需要将其设置到AnnotationAwareAspectJAutoProxyCreator对象中,因此需要我们注入这个对象:
@Configuration
publicclassTargetSourceCreatorBean{
@Autowired
privateBeanFactorybeanFactory;
@Bean
publicAnnotationAwareAspectJAutoProxyCreatorannotationAwareAspectJAutoProxyCreator(){
AnnotationAwareAspectJAutoProxyCreatorcreator=newAnnotationAwareAspectJAutoProxyCreator();
MyTargetSourceCreatormyTargetSourceCreator=newMyTargetSourceCreator();
myTargetSourceCreator.setBeanFactory(beanFactory);
creator.setCustomTargetSourceCreators(myTargetSourceCreator);
returncreator;
}
}
这样,当我们通过getBean获取userServiceImpl的对象时,就会优先生成代理对象,然后在调用执行链的过程中再通过TargetSource.getTarget获取到被代理对象。但是,为什么我们在getTarget方法中调用getBean就能拿到被代理对象呢?
继续探究,通过断点我发现从getTarget进入时,在resolveBeforeInstantiation方法中返回的bean就是null了,而getBeanPostProcessors方法返回的Processors中也没有了AnnotationAwareAspectJAutoProxyCreator对象,也就是没有进入到AbstractAutoProxyCreator.postProcessBeforeInstantiation方法中,所以不会再次获取到代理对象,那AnnotationAwareAspectJAutoProxyCreator对象是在什么时候移除的呢?
带着问题,我开始反推,发现在AbstractBeanFactoryBasedTargetSourceCreator类中有这样一个方法buildInternalBeanFactory:
protectedDefaultListableBeanFactorybuildInternalBeanFactory(ConfigurableBeanFactorycontainingFactory){
DefaultListableBeanFactoryinternalBeanFactory=newDefaultListableBeanFactory(containingFactory);
//RequiredsothatallBeanPostProcessors,Scopes,etcbecomeavailable.
internalBeanFactory.copyConfigurationFrom(containingFactory);
//FilteroutBeanPostProcessorsthatarepartoftheAOPinfrastructure,
//sincethoseareonlymeanttoapplytobeansdefinedintheoriginalfactory.
internalBeanFactory.getBeanPostProcessors().removeIf(beanPostProcessor->
beanPostProcessorinstanceofAopInfrastructureBean);
returninternalBeanFactory;
}
在这里移除掉了所有AopInfrastructureBean的子类,而AnnotationAwareAspectJAutoProxyCreator就是其子类,那这个方法是在哪里调用的呢?继续反推:
protectedDefaultListableBeanFactorygetInternalBeanFactoryForBean(StringbeanName){
synchronized(this.internalBeanFactories){
DefaultListableBeanFactoryinternalBeanFactory=this.internalBeanFactories.get(beanName);
if(internalBeanFactory==null){
internalBeanFactory=buildInternalBeanFactory(this.beanFactory);
this.internalBeanFactories.put(beanName,internalBeanFactory);
}
returninternalBeanFactory;
}
}
publicfinalTargetSourcegetTargetSource(Class>beanClass,StringbeanName){
AbstractBeanFactoryBasedTargetSourcetargetSource=
createBeanFactoryBasedTargetSource(beanClass,beanName);
//创建完targetSource后就移除掉AopInfrastructureBean类型的BeanPostProcessor对象,如AnnotationAwareAspectJAutoProxyCreator
DefaultListableBeanFactoryinternalBeanFactory=getInternalBeanFactoryForBean(beanName);
......
returntargetSource;
}
至此,关于TargetSource接口扩展的原理就搞明白了。
总结
本篇篇幅比较长,主要搞明白Spring代理对象是如何创建的以及AOP链式调用过程,而后面的扩展则是对AOP以及Bean创建过程中一些疑惑的补充,可根据实际情况学习掌握。希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
  