publicabstractclassAbstractAutoProxyCreatorextendsProxyProcessorSupportimplementsSmartInstantiationAwareBeanPostProcessor,BeanFactoryAware{@OverridepublicObjectpostProcessAfterInitialization(@NullableObjectbean,StringbeanName){if(bean!=null){// 如果是FactoryBean,cacheKey是 &+beanName拼接而成,如果benaName为空,则是类名称。ObjectcacheKey=getCacheKey(bean.getClass(),beanName);if(!this.earlyProxyReferences.contains(cacheKey)){// TODO 必要时包装给定的bean,即是否有资格被代理。returnwrapIfNecessary(bean,beanName,cacheKey);}}returnbean;}}
如果需要生成代理(自定义切面、事务等),会调用 wrapIfNecessary()。
wrapIfNecessary() 是这么定义的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
publicabstractclassAbstractAutoProxyCreatorextendsProxyProcessorSupportimplementsSmartInstantiationAwareBeanPostProcessor,BeanFactoryAware{protectedObjectwrapIfNecessary(Objectbean,StringbeanName,ObjectcacheKey){// 省略无关代码...// TODO 重点:如果有需要增强,就创建代理对象,这里会循环此类中所有的方法,如果有增强匹配到类中的方法,就会将增强对象封装到list中。// Create proxy if we have advice.Object[]specificInterceptors=getAdvicesAndAdvisorsForBean(bean.getClass(),beanName,null);if(specificInterceptors!=DO_NOT_PROXY){this.advisedBeans.put(cacheKey,Boolean.TRUE);// TODO 重点:创建代理对象Objectproxy=createProxy(bean.getClass(),beanName,specificInterceptors,newSingletonTargetSource(bean));this.proxyTypes.put(cacheKey,proxy.getClass());returnproxy;}this.advisedBeans.put(cacheKey,Boolean.FALSE);returnbean;}}
publicclassAnnotationAwareAspectJAutoProxyCreatorextendsAspectJAwareAdvisorAutoProxyCreator{@OverrideprotectedList<Advisor>findCandidateAdvisors(){// TODO 从父类中获取,这里获取了所有注入到容器中的Advisor类型的实例。事务的增强实例,就是在这里查找的。// Add all the Spring advisors found according to superclass rules.List<Advisor>advisors=super.findCandidateAdvisors();// Build Advisors for all AspectJ aspects in the bean factory.if(this.aspectJAdvisorsBuilder!=null){// TODO 将beanFactory中缓存的所有bean实例,依次校验是否带有@Aspect注解,如果有,将其中的// 增强方法、切点表达式等信息,封装成Advisor。advisors变量最终存储了所有切面的增强方法封装。advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());}returnadvisors;}}
finalclassInstantiationModelAwarePointcutAdvisorImplimplementsInstantiationModelAwarePointcutAdvisor,AspectJPrecedenceInformation,Serializable{publicInstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcutdeclaredPointcut,MethodaspectJAdviceMethod,AspectJAdvisorFactoryaspectJAdvisorFactory,MetadataAwareAspectInstanceFactoryaspectInstanceFactory,intdeclarationOrder,StringaspectName){// 切点、切面名称、通知方法名称、等等一系列信息的封装this.declaredPointcut=declaredPointcut;// 省略...if(aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()){// 省略...}else{// A singleton aspect.this.pointcut=this.declaredPointcut;this.lazy=false;// TODO 重点,实例化的过程,这里封装了具体的Advicethis.instantiatedAdvice=instantiateAdvice(this.declaredPointcut);}}}
重点方法是 instantiateAdvice(),这里完成了 Advice 的创建。
继续向下跟踪代码:
1
2
3
4
5
6
7
8
9
10
finalclassInstantiationModelAwarePointcutAdvisorImplimplementsInstantiationModelAwarePointcutAdvisor,AspectJPrecedenceInformation,Serializable{privateAdviceinstantiateAdvice(AspectJExpressionPointcutpointcut){// TODO 重点getAdviceAdviceadvice=this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod,pointcut,this.aspectInstanceFactory,this.declarationOrder,this.aspectName);return(advice!=null?advice:EMPTY_ADVICE);}}
publicclassReflectiveAspectJAdvisorFactoryextendsAbstractAspectJAdvisorFactoryimplementsSerializable{publicAdvicegetAdvice(MethodcandidateAdviceMethod,AspectJExpressionPointcutexpressionPointcut,MetadataAwareAspectInstanceFactoryaspectInstanceFactory,intdeclarationOrder,StringaspectName){// 获取切面类Class<?>candidateAspectClass=aspectInstanceFactory.getAspectMetadata().getAspectClass();validate(candidateAspectClass);// 查找切点表达式、五种通知增强注解。@Before等五种。AspectJAnnotation<?>aspectJAnnotation=AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);if(aspectJAnnotation==null){returnnull;}// 省略部分代码...AbstractAspectJAdvicespringAdvice;// TODO 执行判断,针对不同类型的通知,封装不同类型的Advice// 这几个Advice的实现类要记一下。主要以是否实现MethodInterceptor来区分,有的实现了,有的没有。switch(aspectJAnnotation.getAnnotationType()){caseAtPointcut:if(logger.isDebugEnabled()){logger.debug("Processing pointcut '"+candidateAdviceMethod.getName()+"'");}returnnull;caseAtAround:springAdvice=newAspectJAroundAdvice(candidateAdviceMethod,expressionPointcut,aspectInstanceFactory);break;caseAtBefore:springAdvice=newAspectJMethodBeforeAdvice(candidateAdviceMethod,expressionPointcut,aspectInstanceFactory);break;caseAtAfter:springAdvice=newAspectJAfterAdvice(candidateAdviceMethod,expressionPointcut,aspectInstanceFactory);break;caseAtAfterReturning:springAdvice=newAspectJAfterReturningAdvice(candidateAdviceMethod,expressionPointcut,aspectInstanceFactory);AfterReturningafterReturningAnnotation=(AfterReturning)aspectJAnnotation.getAnnotation();if(StringUtils.hasText(afterReturningAnnotation.returning())){springAdvice.setReturningName(afterReturningAnnotation.returning());}break;caseAtAfterThrowing:springAdvice=newAspectJAfterThrowingAdvice(candidateAdviceMethod,expressionPointcut,aspectInstanceFactory);AfterThrowingafterThrowingAnnotation=(AfterThrowing)aspectJAnnotation.getAnnotation();if(StringUtils.hasText(afterThrowingAnnotation.throwing())){springAdvice.setThrowingName(afterThrowingAnnotation.throwing());}break;default:thrownewUnsupportedOperationException("Unsupported advice type on method: "+candidateAdviceMethod);}// 省略...returnspringAdvice;}}
publicabstractclassAopUtils{// 步骤一publicstaticbooleancanApply(Advisoradvisor,Class<?>targetClass,booleanhasIntroductions){if(advisorinstanceofIntroductionAdvisor){return((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass);}elseif(advisorinstanceofPointcutAdvisor){PointcutAdvisorpca=(PointcutAdvisor)advisor;//切点表达式匹配。returncanApply(pca.getPointcut(),targetClass,hasIntroductions);}else{// It doesn't have a pointcut so we assume it applies.returntrue;}}publicstaticbooleancanApply(Pointcutpc,Class<?>targetClass,booleanhasIntroductions){// 省略...// 这里做了切入点表达式的匹配,匹配通过的返回true,具体的匹配过程不用看,不是重点。for(Class<?>clazz:classes){Method[]methods=ReflectionUtils.getAllDeclaredMethods(clazz);for(Methodmethod:methods){if(introductionAwareMethodMatcher!=null?introductionAwareMethodMatcher.matches(method,targetClass,hasIntroductions):methodMatcher.matches(method,targetClass)){returntrue;}}}returnfalse;}}
graph LR;
B(findCandidateAdvisors) -->|One| C(super.findCandidateAdvisors)
C --> CA{findAdvisorBeans}
CA -->|One| CAA(beanNamesForTypeIncludingAncestors)
CA -->|Two| CAB(beanFactory.getBean)
graph LR;
B(findCandidateAdvisors) -->|One| C(super.findCandidateAdvisors)
C --> CA{findAdvisorBeans}
CA -->|One| CAA(beanNamesForTypeIncludingAncestors)
CA -->|Two| CAB(beanFactory.getBean)
子类调用流程:
graph TB;
B(findCandidateAdvisors) -->|Two| D(buildAspectJAdvisors)
D -->|ForEach| E(beanNames)
E --> F(isAspect) -->|true| G{getAdvisors}
G -->|One| GA(getAdvisorMethods)
GA --> GAA1(doWithMethods) --> GAA2("getAnnotation(method, Pointcut.class)")
G -->|Two| GB(getAdvisor)
GB --> GBA(getPointcut)
GBA --> GBAA(findAspectJAnnotationOnMethod) -->|forEach| GBAA1(ASPECTJ_ANNOTATION_CLASSES)
GBAA1 --> GBAA2(findAnnotation) --> GBAA3("new AspectJAnnotation<>(result)")
graph TB;
B(findCandidateAdvisors) -->|Two| D(buildAspectJAdvisors)
D -->|ForEach| E(beanNames)
E --> F(isAspect) -->|true| G{getAdvisors}
G -->|One| GA(getAdvisorMethods)
GA --> GAA1(doWithMethods) --> GAA2("getAnnotation(method, Pointcut.class)")
G -->|Two| GB(getAdvisor)
GB --> GBA(getPointcut)
GBA --> GBAA(findAspectJAnnotationOnMethod) -->|forEach| GBAA1(ASPECTJ_ANNOTATION_CLASSES)
GBAA1 --> GBAA2(findAnnotation) --> GBAA3("new AspectJAnnotation<>(result)")