Spring源码-Aspect-Bean解析流程
自动配置
方式一:注解启用
注解 EnableAspectJAutoProxy
启用 Spring Aspect 切面。
|
|
注解 EnableAspectJAutoProxy
底层实现是注册 AnnotationAwareAspectJAutoProxyCreator.class BeanDefinition 到 Spring 容器中。
- org.springframework.context.annotation.AspectJAutoProxyRegistrar#registerBeanDefinitions
- org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)
- org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
- 核心代码如下
- registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
- beanDefinition.getPropertyValues().add(“order”, Ordered.HIGHEST_PRECEDENCE);
- beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
方式二:SpringBoot 自动配置
自动配置类中启用了 @EnableAspectJAutoProxy
。
|
|
类定义
|
|
关键方法
关键方法列表
- 解析 AOP 配置
- Spring 扩展点 postProcessBeforeInstantiation 方法
- org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation
- 根据 AOP 配置包装 bean
- Spring 扩展点 postProcessAfterInitialization
- org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
关键方法详情
解析 AOP 配置 postProcessBeforeInstantiation
入口方法
- org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation 继承父类 postProcessBeforeInstantiation 方法。
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation
流程
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getCacheKey
- 功能:构建缓存 key
- 逻辑:if 存在 beanName 且为 FactoryBean,返回 BeanFactory.FACTORY_BEAN_PREFIX + beanName。else-if 存在 beanName,返回 beanName。else 返回 beanClass。
- 如果缓存 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#advisedBeans 中已经解析 bean 解析结果,则退出方法。
- 满足 isInfrastructureClass(beanClass) 条件的 bean 不需要 AOP 代理。
- 方法:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass
- 功能1:Advice, Advisor, Pointcut, AopInfrastructureBean 类型的 Bean 满足条件 isInfrastructureClass,不需要被代理。底层调用 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#isInfrastructureClass
- 功能2:注解 @Aspect 修饰,且非 ajc 编译的 bean 满足条件 isAspect,进而满足条件 isInfrastructureClass,不需要被代理。底层调用 org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#isAspect
- 满足 shouldSkip(beanClass, beanName) 条件的 bean 不需要 AOP 代理。
- 方法:org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
- 获取所有的 Advisor。调用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors。详情参见《分支 findCandidateAdvisors》
- 如果当前 bean 实现了 AspectJPointcutAdvisor,则跳过。目前未看到 AspectJPointcutAdvisor 使用场景,当前的 advisor 均为 InstantiationModelAwarePointcutAdvisorImpl,并未继承 AspectJPointcutAdvisor。
- 判断是否是 OriginalInstance,即 bean name 后缀为 “.ORIGINAL”,则跳过。
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip
- org.springframework.aop.framework.autoproxy.AutoProxyUtils#isOriginalInstance
- 如果存在用户自定义的创建代理逻辑 customTargetSourceCreators,则使用该工具创建代理。默认无。
此处支持 AOP 扩展点 TargetSource,该扩展点无使用场景,忽略相关逻辑。
根据 AOP 配置包装 bean postProcessAfterInitialization
入口方法
- org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization 继承父类 postProcessAfterInitialization 方法。
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
流程
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getCacheKey 获取缓存 key。
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary 参见《分支 wrapIfNecessary》。
重要分支
分支 findCandidateAdvisors
入口方法
- org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
主流程
- 获取所有的 Advisor。
- 方法:
- org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findCandidateAdvisors
- org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans
- 获取容器中所有类型为 Advisor.class 的 bean name。
- 如果缓存 org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#cachedAdvisorBeanNames 不为空,则直接使用缓存。
- 从 bean factory 及祖先 bean factory 中找到所有 Advisor.class 类型的 bean name,存储到缓存中。底层调用 org.springframework.beans.factory.BeanFactoryUtils#beanNamesForTypeIncludingAncestors(org.springframework.beans.factory.ListableBeanFactory, java.lang.Class, boolean, boolean),allowEagerInit 参数为 false。
- 遍历上一步获取到的 bean name,如果满足 isEligibleBean 条件(当前始终为 true),则调用 beanFactory#getBean 构造为 bean。
- isEligibleBean 条件当前始终为 true。当 Spring 未启用 AOP 时(即未注册 AnnotationAwareAspectJAutoProxyCreator,而是注册 InfrastructureAdvisorAutoProxyCreator 时),存在有效判断逻辑。
- 底层调用 org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.BeanFactoryAdvisorRetrievalHelperAdapter#isEligibleBean,继续调用 org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#isEligibleAdvisorBean,始终返回 true。
- AnnotationAwareAspectJAutoProxyCreator 是 AbstractAdvisorAutoProxyCreator 的子类,且未重写 isEligibleAdvisorBean 方法。
- 方法:
- 获取所有 Spring AOP 配置的切面 Bean。
- 方法:org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
- 具体步骤参见章节《分支 buildAspectJAdvisors》。
- 返回上述两个步骤的并集,即 Advisor 类型 bean 与切面 bean 构造的 advisor 的并集。
分支 buildAspectJAdvisors
构建全量 advisor。
入口方法 1
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation
- org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
- org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
- org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
入口方法 2
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
- org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
- org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
- org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
- org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
功能
获取所有 Spring AOP 配置的切面 Bean。
方法
- org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
流程
- 获取所有 Spring AOP 配置的切面 Bean 的 bean name。
- 如果缓存 org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#aspectBeanNames 为空,则解析切面 bean 并返回。
- 从 bean factory 及祖先 bean factory 中找到所有 Object.class 类型的 bean name。底层调用方法 org.springframework.beans.factory.BeanFactoryUtils#beanNamesForTypeIncludingAncestors(org.springframework.beans.factory.ListableBeanFactory, java.lang.Class, boolean, boolean),allowEagerInit 参数为 false。
- 如果不满足 isEligibleBean 条件,则忽略该 bean name。
- 功能:与
<aop:include>
配置相关。当前使用 Spring 注解配置,未进行 XML 配置,因此满足 isEligibleBean 条件。 - 调用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.BeanFactoryAspectJAdvisorsBuilderAdapter#isEligibleBean,底层调用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isEligibleAspectBean,allowEagerInit 参数为 false。
- 功能:与
- 获取 bean 的类型,如果无法获取,则忽略该 bean。例如因无法实例化 factory bean而无法获得 type。调用 beanFactory.getType 方法,allowFactoryBeanInit 参数为 false。
- 判断 bean 是否是 Spring AOP 切面 bean,如果不是,则忽略该 bean。具体是判断 bean 是否被注解
@Aspect
修饰,且非 ajc 编译。原因是使用AspectJ语言(非 Spring AOP)编写的切面在通过 ajc 编译得到时也会存在@Aspect注解。调用 org.springframework.aop.aspectj.annotation.AspectJAdvisorFactory#isAspect 方法。 - 如果切面 bean 的 AjType 特性(Aspect 注解的 value 值配置)是单例。封装为 BeanFactoryAspectInstanceFactory,如果 bean 是单例,则存储到缓存 BeanFactoryAspectJAdvisorsBuilder#advisorsCache,否则存储到缓存 BeanFactoryAspectJAdvisorsBuilder#aspectFactoryCache。调用 advisorFactory#getAdvisors 构造 Advisor。
- 如果切面 bean 的 AjType 特性,则 bean 也必须是非单例的。封装为 PrototypeAspectInstanceFactory,存储到缓存 BeanFactoryAspectJAdvisorsBuilder#aspectFactoryCache。调用 advisorFactory#getAdvisors 构造 Advisor。
- 如果缓存 org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#aspectBeanNames 不为空,使用缓存构造 advisor。
- 遍历缓存中的 aspectNames。
- 如果存在于缓存 BeanFactoryAspectJAdvisorsBuilder#advisorsCache 中,则直接使用缓存中的 advisor。
- 如果存在于缓存 BeanFactoryAspectJAdvisorsBuilder#aspectFactoryCache 中,则调用 advisorFactory#getAdvisors 构造 advisor。
方法介绍 isAspect
org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#isAspect
We consider something to be an AspectJ aspect suitable for use by the Spring AOP system if it has the @Aspect annotation, and was not compiled by ajc. The reason for this latter test is that aspects written in the code-style (AspectJ language) also have the annotation present when compiled by ajc with the -1.5 flag, yet they cannot be consumed by Spring AOP.
我们认为一个对象是适合由Spring AOP系统使用的AspectJ切面,如果它具有@Aspect注解,并且不是由ajc(AspectJ编译器)编译的。进行后者的检查的原因是,使用AspectJ语言(代码风格)编写的切面在通过ajc编译时(使用-1.5标志),也会存在@Aspect注解,但它们无法被Spring AOP使用。
org.aspectj.internal.lang.reflect.AjTypeImpl#getPerClause
org.aspectj.lang.annotation.Aspect 是 AspectJ 提供的注解,用于定义切面(Aspect)。它的 value 属性用于指定切面的实例化模式(即切面的生命周期),默认是单例(singleton),但也可以通过特定语法配置其他作用域。
可选值
值 | 说明 | 示例 |
---|---|---|
"" (空字符串) | 默认值,表示切面是单例(Singleton)模式,整个应用共享同一个实例。 | @Aspect("") 或 @Aspect |
"perthis(...)" | 为每个匹配切点的目标对象(this)创建一个切面实例。 | @Aspect("perthis(execution(* com.example.Service.*(..)))") |
"pertarget(...)" | 为每个匹配切点的被代理对象(target)创建一个切面实例。 | @Aspect("pertarget(execution(* com.example.Dao.*(..)))") |
"percflow(...)" | 为每个控制流(例如方法调用栈)创建一个切面实例。 | @Aspect("percflow(execution(* com.example.Controller.*(..)))") |
"percflowbelow(...)" | 为每个控制流及子控制流创建一个切面实例。 | @Aspect("percflowbelow(execution(* com.example.Service.*(..)))") |
分支 getAdvisors
方法
- org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors
流程
- 获取切面 bean 的 class。
- 获取切面 bean 的 beanName。
- 校验切面 bean 的 class。
- 方法:org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#validate
- Aspect 注解校验等,忽略。
- Spring AOP 不支持
ajType.getPerClause().getKind()
为 PerClauseKind.PERCFLOW 或 PerClauseKind.PERCFLOWBELOW。
- 懒加载包装器。new LazySingletonAspectInstanceFactoryDecorator。
- 获取切面 bean 的 class 中所有的切面方法,并根据指定规则排序。
- 方法:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisorMethods
- 筛选条件:用户自定义方法,且方法未被注解
@Pointcut
修饰(Exclude @Pointcut methods)。 - 注意:此处可能包含无效的切面方法,即切面类中未被任何切面相关注解修饰的方法。
- 排序规则:首先,注解顺序递增 Around.class,Before.class,After.class,AfterReturning.class,AfterThrowing.class;其次,方法名称顺序。
- for-each method 遍历切面 method 构建 advisor。
- 方法:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisor
- 校验切面 bean 的 class。在前面步骤中已经进行校验。方法:org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#validate。
- 构建 Pointcut,封装为 AspectJExpressionPointcut。
- 方法:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getPointcut
- 获取方法上的 AspectJ 注解,只取第一个找到的注解(预期方法仅被一个注解修饰),查询顺序为 Pointcut.class,Around.class,Before.class,After.class,AfterReturning.class,AfterThrowing.class。
- 方法:org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#findAspectJAnnotationOnMethod
- 注意,因为在获取 AspectJ 方法时已经排除了注解
@Pointcut
,因此此处该注解无效。
- new AspectJExpressionPointcut。
- 配置 AspectJExpressionPointcut 的表达式,beanFactory。
- 如果方法是无效的 AspectJ 方法,则返回 null,并在上层方法中被忽略。
- new InstantiationModelAwarePointcutAdvisorImpl。创建 AspectJPointcutAdvisor 的实现类。
- 如果具有 lazy 属性(包括 PerClauseKind.PERTHIS,PerClauseKind.PERTARGET,PerClauseKind.PERTYPEWITHIN),进行相关适配,并结束方法。
- else (即如果是单例类),实例化 advice。底层调用方法 org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl#instantiateAdvice,继续调用 org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvice。
- 如果 AspectJ bean 具有 lazy 属性,则添加 SyntheticInstantiationAdvisor 作为第一个 advisor。
- 获取 AspectJ bean 中的所有字段。
- 方法:java.lang.Class#getDeclaredFields
- 范围:This includes public, protected, default (package) access, and private fields, but excludes inherited fields.
- for-each fields 遍历所有字段,构造引入字段。
- 方法:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getDeclareParentsAdvisor
- 如果字段未被注解
@DeclareParents
修饰,则忽略。 - new DeclareParentsAdvisor。封装为 DeclareParentsAdvisor。底层创建 new DelegatePerTargetObjectIntroductionInterceptor。
|
|
分支 getAdvice
方法
- org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvice
流程
- 获取切面 bean 的 class。
- 校验切面 bean 的 class。在前面步骤中已经进行校验。方法:org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#validate。
- 获取方法上的 AspectJ 注解,只取第一个找到的注解(预期方法仅被一个注解修饰),查询顺序为 Pointcut.class,Around.class,Before.class,After.class,AfterReturning.class,AfterThrowing.class。方法:org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#findAspectJAnnotationOnMethod。
- 解析方法上的 AspectJ 注解,封装为 Advice。
- switch (aspectJAnnotation.getAnnotationType())
- case AtPointcut: null。忽略 Pointcut 注解。
- case AtAround: new AspectJAroundAdvice
- case AtBefore: new AspectJMethodBeforeAdvice
- case AtAfter: new AspectJAfterAdvice
- case AtAfterReturning: new AspectJAfterReturningAdvice
- case AtAfterThrowing: new AspectJAfterThrowingAdvice
- 配置属性,包括切面 bean name,定义顺序等。
- 绑定参数特殊参数 JoinPoint、ProceedingJoinPoint 和 JoinPoint.StaticPart。调用 org.springframework.aop.aspectj.AbstractAspectJAdvice#setArgumentNamesFromStringArray。
- 绑定用户自定义参数(通过形参名称映射)。调用方法 org.springframework.aop.aspectj.AbstractAspectJAdvice#calculateArgumentBindings,继续调用 org.springframework.aop.aspectj.AbstractAspectJAdvice#bindArgumentsByName。
分支 wrapIfNecessary
入口方法 1
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
入口方法 2
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
流程
- 前置判断,略。
- 是否存在自定义代理逻辑(扩展点)。读取缓存 AbstractAutoProxyCreator#targetSourcedBeans。
- 是否需要代理。读缓存 AbstractAutoProxyCreator#advisedBeans。
- 是否是切面基础类。org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass
- 是否需要跳过。org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
- 获取匹配的 Advisors。
- 方法:org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean,org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors。
- 获取全量的 advisor。调用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors,详情参见《分支 findCandidateAdvisors》。
- 从全量 advisor 中筛选匹配的 advisor。
- 方法:org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply,org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply。
- 详情参见《分支 findAdvisorsThatCanApply》。
- 扩展 advisor。
- 方法:org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#extendAdvisors,org.springframework.aop.aspectj.AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary
- 校验是否存在 AspectJAdvice,如果存在,会补充 ExposeInvocationInterceptor.ADVISOR(如果当前不存在该 advisor)。
advisors.add(0, ExposeInvocationInterceptor.ADVISOR)
。 - ExposeInvocationInterceptor 关联 org.springframework.context.annotation.EnableAspectJAutoProxy#exposeProxy。
- 对 advisor 排序。
- org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#sortAdvisors
- 使用了 AspectJPrecedenceComparator 和 AnnotationAwareOrderComparator
- 如果A和B在不同的方面中定义,那么排序值最低的方面中的通知具有最高的优先级。如果A和B在同一个方面中定义,如果A或B中的一个是after通知的形式,那么在方面中最后声明的通知具有最高优先级。如果A和B都不是after通知的形式,那么在方面中首先声明的通知具有最高优先级。重要:此比较器与AspectJ的PartialOrder排序实用程序一起使用。因此,与普通的Comparator不同,这个Comparator的返回值为0意味着我们不关心排序,也不是说两个元素必须排序相同。
- 创建 SingletonTargetSource 持有 bean。org.springframework.aop.target.SingletonTargetSource#SingletonTargetSource
- 创建代理。org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
- 配置属性。org.springframework.aop.framework.autoproxy.AutoProxyUtils#exposeTargetClass
- 构建 advisor。
- 方法:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#buildAdvisors。
- 详情参见《分支 buildAdvisors》。
- 创建代理。
- org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)
- org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy
- org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy 创建 JdkDynamicAopProxy 或 ObjenesisCglibAopProxy。
- org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)
分支 findAdvisorsThatCanApply
方法
- org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply
流程
- for-each advisors。遍历 advisors,筛选 IntroductionAdvisor。
- 如果 advisor instanceof IntroductionAdvisor 且满足 canApply 方法。
- 优先处理 IntroductionAdvisor,因为后续非 IntroductionAdvisor 的解析依赖 IntroductionAdvisor。
- canApply 方法签名是 org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Advisor, java.lang.Class),org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Advisor, java.lang.Class, boolean)。
- for-each advisors。遍历 advisors,筛选非 IntroductionAdvisor。
- 如果
- canApply 方法签名是 org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Advisor, java.lang.Class, boolean)。
分支 canApply
方法
- org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Advisor, java.lang.Class, boolean)
流程
- if (advisor instanceof IntroductionAdvisor),then ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);。
- if (advisor instanceof PointcutAdvisor),then canApply(pca.getPointcut(), targetClass, hasIntroductions);。
- 方法:org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class, boolean)。
- 类级别判断 pc.getClassFilter().matches。
- 方法级别简略判断 (pc.getMethodMatcher() == MethodMatcher.TRUE)
- 方法级别详细判断。
- 如果目标类被代码,则获取其原始类。调用 org.springframework.util.ClassUtils#getUserClass(java.lang.Class)。
- 获取目标类的所有接口类。调用 org.springframework.util.ClassUtils#getAllInterfacesForClassAsSet(java.lang.Class)。
- for-each classes。遍历 classes,获取 class 中的所有方法,并校验是否匹配。
- 获取方法,包括子类与父类方法。调用 org.springframework.util.ReflectionUtils#getAllDeclaredMethods。
- for-each methods。遍历 methods,校验是否匹配。
- 如果满足 (methodMatcher instanceof IntroductionAwareMethodMatcher),则调用
- org.springframework.aop.IntroductionAwareMethodMatcher#matches。当前使用的 AspectJExpressionPointcut 是 IntroductionAwareMethodMatcher 的子类。
- 否则调用 org.springframework.aop.MethodMatcher#matches(java.lang.reflect.Method, java.lang.Class)。
- else true。
分支 buildAdvisors
方法
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#buildAdvisors
流程
- 方法:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#resolveInterceptorNames
- for-each allInterceptors
- 方法:org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#wrap。
- if (adviceObject instanceof Advisor), then (Advisor) adviceObject;
- if (advice instanceof MethodInterceptor), then new DefaultPointcutAdvisor
- for-each adapters
- if (adapter.supportsAdvice(advice)), then new DefaultPointcutAdvisor