这一次搞懂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(); } protectedList findEligibleAdvisors(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; }
在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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。