Spring源码-Aspect-Bean解析流程

总结摘要
Spring AOP Aspect Bean解析流程

自动配置

方式一:注解启用

注解 EnableAspectJAutoProxy启用 Spring Aspect 切面。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// org.springframework.context.annotation.EnableAspectJAutoProxy
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {}


// org.springframework.context.annotation.AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // ...
        
        // 注册 AnnotationAwareAspectJAutoProxyCreator.class
		// Order 设置为最高优先级。beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
    }
}

注解 EnableAspectJAutoProxy底层实现是注册 AnnotationAwareAspectJAutoProxyCreator.class BeanDefinition 到 Spring 容器中。

  1. org.springframework.context.annotation.AspectJAutoProxyRegistrar#registerBeanDefinitions
  2. org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)
  3. org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
    1. 核心代码如下
    2. registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    3. beanDefinition.getPropertyValues().add(“order”, Ordered.HIGHEST_PRECEDENCE);
    4. beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

方式二:SpringBoot 自动配置

自动配置类中启用了 @EnableAspectJAutoProxy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
@AutoConfiguration
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(Advice.class)
	static class AspectJAutoProxyingConfiguration {

		@Configuration(proxyBeanMethods = false)
		@EnableAspectJAutoProxy(proxyTargetClass = false)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
		static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration(proxyBeanMethods = false)
		@EnableAspectJAutoProxy(proxyTargetClass = true)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
				matchIfMissing = true)
		static class CglibAutoProxyConfiguration {

		}

	}
}

类定义

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// org.springframework.aop.framework.AopInfrastructureBean
public interface AopInfrastructureBean {}

// org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {}

// org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {}


// ======================================================================

// org.springframework.aop.framework.ProxyConfig
public class ProxyConfig implements Serializable {}

// org.springframework.aop.framework.ProxyProcessorSupport
public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean {}

// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    	private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
}

// org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {}

// org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {}

// org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {}

关键方法

关键方法列表

  1. 解析 AOP 配置
    1. Spring 扩展点 postProcessBeforeInstantiation 方法
    2. org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation
    3. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation
  2. 根据 AOP 配置包装 bean
    1. Spring 扩展点 postProcessAfterInitialization
    2. org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization
    3. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

关键方法详情

解析 AOP 配置 postProcessBeforeInstantiation

入口方法

  1. org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation 继承父类 postProcessBeforeInstantiation 方法。
  2. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation

流程

  1. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getCacheKey
    1. 功能:构建缓存 key
    2. 逻辑:if 存在 beanName 且为 FactoryBean,返回 BeanFactory.FACTORY_BEAN_PREFIX + beanName。else-if 存在 beanName,返回 beanName。else 返回 beanClass。
  2. 如果缓存 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#advisedBeans 中已经解析 bean 解析结果,则退出方法。
  3. 满足 isInfrastructureClass(beanClass) 条件的 bean 不需要 AOP 代理。
    1. 方法:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass
    2. 功能1:Advice, Advisor, Pointcut, AopInfrastructureBean 类型的 Bean 满足条件 isInfrastructureClass,不需要被代理。底层调用 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#isInfrastructureClass
    3. 功能2:注解 @Aspect 修饰,且非 ajc 编译的 bean 满足条件 isAspect,进而满足条件 isInfrastructureClass,不需要被代理。底层调用 org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#isAspect
  4. 满足 shouldSkip(beanClass, beanName) 条件的 bean 不需要 AOP 代理。
    1. 方法:org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
    2. 获取所有的 Advisor。调用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors。详情参见《分支 findCandidateAdvisors》
    3. 如果当前 bean 实现了 AspectJPointcutAdvisor,则跳过。目前未看到 AspectJPointcutAdvisor 使用场景,当前的 advisor 均为 InstantiationModelAwarePointcutAdvisorImpl,并未继承 AspectJPointcutAdvisor。
    4. 判断是否是 OriginalInstance,即 bean name 后缀为 “.ORIGINAL”,则跳过。
      1. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip
      2. org.springframework.aop.framework.autoproxy.AutoProxyUtils#isOriginalInstance
  5. 如果存在用户自定义的创建代理逻辑 customTargetSourceCreators,则使用该工具创建代理。默认无。

此处支持 AOP 扩展点 TargetSource,该扩展点无使用场景,忽略相关逻辑。

根据 AOP 配置包装 bean postProcessAfterInitialization

入口方法

  1. org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization 继承父类 postProcessAfterInitialization 方法。
  2. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

流程

  1. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getCacheKey 获取缓存 key。
  2. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary 参见《分支 wrapIfNecessary》。

重要分支

分支 findCandidateAdvisors

入口方法

  1. org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors

主流程

  1. 获取所有的 Advisor。
    1. 方法:
      1. org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findCandidateAdvisors
      2. org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans
    2. 获取容器中所有类型为 Advisor.class 的 bean name。
      1. 如果缓存 org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#cachedAdvisorBeanNames 不为空,则直接使用缓存。
      2. 从 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。
    3. 遍历上一步获取到的 bean name,如果满足 isEligibleBean 条件(当前始终为 true),则调用 beanFactory#getBean 构造为 bean。
      1. isEligibleBean 条件当前始终为 true。当 Spring 未启用 AOP 时(即未注册 AnnotationAwareAspectJAutoProxyCreator,而是注册 InfrastructureAdvisorAutoProxyCreator 时),存在有效判断逻辑。
      2. 底层调用 org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.BeanFactoryAdvisorRetrievalHelperAdapter#isEligibleBean,继续调用 org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#isEligibleAdvisorBean,始终返回 true。
      3. AnnotationAwareAspectJAutoProxyCreator 是 AbstractAdvisorAutoProxyCreator 的子类,且未重写 isEligibleAdvisorBean 方法。
  2. 获取所有 Spring AOP 配置的切面 Bean。
    1. 方法:org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
    2. 具体步骤参见章节《分支 buildAspectJAdvisors》。
  3. 返回上述两个步骤的并集,即 Advisor 类型 bean 与切面 bean 构造的 advisor 的并集。

分支 buildAspectJAdvisors

构建全量 advisor。

入口方法 1

  1. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation
  2. org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
  3. org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
  4. org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors

入口方法 2

  1. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
  2. org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
  3. org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
  4. org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
  5. org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors

功能

获取所有 Spring AOP 配置的切面 Bean。

方法

  1. org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors

流程

  1. 获取所有 Spring AOP 配置的切面 Bean 的 bean name。
    1. 如果缓存 org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#aspectBeanNames 为空,则解析切面 bean 并返回。
    2. 从 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。
    3. 如果不满足 isEligibleBean 条件,则忽略该 bean name。
      1. 功能:与 <aop:include>配置相关。当前使用 Spring 注解配置,未进行 XML 配置,因此满足 isEligibleBean 条件。
      2. 调用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.BeanFactoryAspectJAdvisorsBuilderAdapter#isEligibleBean,底层调用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isEligibleAspectBean,allowEagerInit 参数为 false。
    4. 获取 bean 的类型,如果无法获取,则忽略该 bean。例如因无法实例化 factory bean而无法获得 type。调用 beanFactory.getType 方法,allowFactoryBeanInit 参数为 false。
    5. 判断 bean 是否是 Spring AOP 切面 bean,如果不是,则忽略该 bean。具体是判断 bean 是否被注解 @Aspect修饰,且非 ajc 编译。原因是使用AspectJ语言(非 Spring AOP)编写的切面在通过 ajc 编译得到时也会存在@Aspect注解。调用 org.springframework.aop.aspectj.annotation.AspectJAdvisorFactory#isAspect 方法。
    6. 如果切面 bean 的 AjType 特性(Aspect 注解的 value 值配置)是单例。封装为 BeanFactoryAspectInstanceFactory,如果 bean 是单例,则存储到缓存 BeanFactoryAspectJAdvisorsBuilder#advisorsCache,否则存储到缓存 BeanFactoryAspectJAdvisorsBuilder#aspectFactoryCache。调用 advisorFactory#getAdvisors 构造 Advisor。
    7. 如果切面 bean 的 AjType 特性,则 bean 也必须是非单例的。封装为 PrototypeAspectInstanceFactory,存储到缓存 BeanFactoryAspectJAdvisorsBuilder#aspectFactoryCache。调用 advisorFactory#getAdvisors 构造 Advisor。
  2. 如果缓存 org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#aspectBeanNames 不为空,使用缓存构造 advisor。
    1. 遍历缓存中的 aspectNames。
    2. 如果存在于缓存 BeanFactoryAspectJAdvisorsBuilder#advisorsCache 中,则直接使用缓存中的 advisor。
    3. 如果存在于缓存 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

方法

  1. org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors

流程

  1. 获取切面 bean 的 class。
  2. 获取切面 bean 的 beanName。
  3. 校验切面 bean 的 class。
    1. 方法:org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#validate
    2. Aspect 注解校验等,忽略。
    3. Spring AOP 不支持 ajType.getPerClause().getKind()为 PerClauseKind.PERCFLOW 或 PerClauseKind.PERCFLOWBELOW。
  4. 懒加载包装器。new LazySingletonAspectInstanceFactoryDecorator。
  5. 获取切面 bean 的 class 中所有的切面方法,并根据指定规则排序。
    1. 方法:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisorMethods
    2. 筛选条件:用户自定义方法,且方法未被注解 @Pointcut修饰(Exclude @Pointcut methods)。
    3. 注意:此处可能包含无效的切面方法,即切面类中未被任何切面相关注解修饰的方法。
    4. 排序规则:首先,注解顺序递增 Around.class,Before.class,After.class,AfterReturning.class,AfterThrowing.class;其次,方法名称顺序。
  6. for-each method 遍历切面 method 构建 advisor。
    1. 方法:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisor
    2. 校验切面 bean 的 class。在前面步骤中已经进行校验。方法:org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#validate。
    3. 构建 Pointcut,封装为 AspectJExpressionPointcut。
      1. 方法:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getPointcut
      2. 获取方法上的 AspectJ 注解,只取第一个找到的注解(预期方法仅被一个注解修饰),查询顺序为 Pointcut.class,Around.class,Before.class,After.class,AfterReturning.class,AfterThrowing.class。
        1. 方法:org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#findAspectJAnnotationOnMethod
        2. 注意,因为在获取 AspectJ 方法时已经排除了注解 @Pointcut,因此此处该注解无效。
      3. new AspectJExpressionPointcut。
      4. 配置 AspectJExpressionPointcut 的表达式,beanFactory。
    4. 如果方法是无效的 AspectJ 方法,则返回 null,并在上层方法中被忽略。
    5. new InstantiationModelAwarePointcutAdvisorImpl。创建 AspectJPointcutAdvisor 的实现类。
      1. 如果具有 lazy 属性(包括 PerClauseKind.PERTHIS,PerClauseKind.PERTARGET,PerClauseKind.PERTYPEWITHIN),进行相关适配,并结束方法。
      2. else (即如果是单例类),实例化 advice。底层调用方法 org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl#instantiateAdvice,继续调用 org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvice。
  7. 如果 AspectJ bean 具有 lazy 属性,则添加 SyntheticInstantiationAdvisor 作为第一个 advisor。
  8. 获取 AspectJ bean 中的所有字段。
    1. 方法:java.lang.Class#getDeclaredFields
    2. 范围:This includes public, protected, default (package) access, and private fields, but excludes inherited fields.
  9. for-each fields 遍历所有字段,构造引入字段。
    1. 方法:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getDeclareParentsAdvisor
    2. 如果字段未被注解 @DeclareParents修饰,则忽略。
    3. new DeclareParentsAdvisor。封装为 DeclareParentsAdvisor。底层创建 new DelegatePerTargetObjectIntroductionInterceptor。
1
2
3
4
5
6
7
// org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl
final class InstantiationModelAwarePointcutAdvisorImpl
		implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable {}


// org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {}

分支 getAdvice

方法

  1. org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvice

流程

  1. 获取切面 bean 的 class。
  2. 校验切面 bean 的 class。在前面步骤中已经进行校验。方法:org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#validate。
  3. 获取方法上的 AspectJ 注解,只取第一个找到的注解(预期方法仅被一个注解修饰),查询顺序为 Pointcut.class,Around.class,Before.class,After.class,AfterReturning.class,AfterThrowing.class。方法:org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#findAspectJAnnotationOnMethod。
  4. 解析方法上的 AspectJ 注解,封装为 Advice。
    1. switch (aspectJAnnotation.getAnnotationType())
    2. case AtPointcut: null。忽略 Pointcut 注解。
    3. case AtAround: new AspectJAroundAdvice
    4. case AtBefore: new AspectJMethodBeforeAdvice
    5. case AtAfter: new AspectJAfterAdvice
    6. case AtAfterReturning: new AspectJAfterReturningAdvice
    7. case AtAfterThrowing: new AspectJAfterThrowingAdvice
  5. 配置属性,包括切面 bean name,定义顺序等。
  6. 绑定参数特殊参数 JoinPoint、ProceedingJoinPoint 和 JoinPoint.StaticPart。调用 org.springframework.aop.aspectj.AbstractAspectJAdvice#setArgumentNamesFromStringArray。
  7. 绑定用户自定义参数(通过形参名称映射)。调用方法 org.springframework.aop.aspectj.AbstractAspectJAdvice#calculateArgumentBindings,继续调用 org.springframework.aop.aspectj.AbstractAspectJAdvice#bindArgumentsByName。

分支 wrapIfNecessary

入口方法 1

  1. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
  2. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary

入口方法 2

  1. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
  2. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference
  3. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference
  4. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary

流程

  1. 前置判断,略。
    1. 是否存在自定义代理逻辑(扩展点)。读取缓存 AbstractAutoProxyCreator#targetSourcedBeans。
    2. 是否需要代理。读缓存 AbstractAutoProxyCreator#advisedBeans。
    3. 是否是切面基础类。org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass
    4. 是否需要跳过。org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
  2. 获取匹配的 Advisors。
    1. 方法:org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean,org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors。
    2. 获取全量的 advisor。调用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors,详情参见《分支 findCandidateAdvisors》。
    3. 从全量 advisor 中筛选匹配的 advisor。
      1. 方法:org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply,org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply。
      2. 详情参见《分支 findAdvisorsThatCanApply》。
    4. 扩展 advisor。
      1. 方法:org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#extendAdvisors,org.springframework.aop.aspectj.AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary
      2. 校验是否存在 AspectJAdvice,如果存在,会补充 ExposeInvocationInterceptor.ADVISOR(如果当前不存在该 advisor)。advisors.add(0, ExposeInvocationInterceptor.ADVISOR)
      3. ExposeInvocationInterceptor 关联 org.springframework.context.annotation.EnableAspectJAutoProxy#exposeProxy。
    5. 对 advisor 排序。
      1. org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#sortAdvisors
      2. 使用了 AspectJPrecedenceComparator 和 AnnotationAwareOrderComparator
      3. 如果A和B在不同的方面中定义,那么排序值最低的方面中的通知具有最高的优先级。如果A和B在同一个方面中定义,如果A或B中的一个是after通知的形式,那么在方面中最后声明的通知具有最高优先级。如果A和B都不是after通知的形式,那么在方面中首先声明的通知具有最高优先级。重要:此比较器与AspectJ的PartialOrder排序实用程序一起使用。因此,与普通的Comparator不同,这个Comparator的返回值为0意味着我们不关心排序,也不是说两个元素必须排序相同。
  3. 创建 SingletonTargetSource 持有 bean。org.springframework.aop.target.SingletonTargetSource#SingletonTargetSource
  4. 创建代理。org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
    1. 配置属性。org.springframework.aop.framework.autoproxy.AutoProxyUtils#exposeTargetClass
  5. 构建 advisor。
    1. 方法:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#buildAdvisors。
    2. 详情参见《分支 buildAdvisors》。
  6. 创建代理。
    1. org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)
    2. org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy
    3. org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy 创建 JdkDynamicAopProxy 或 ObjenesisCglibAopProxy。
    4. org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)

分支 findAdvisorsThatCanApply

方法

  1. org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply

流程

  1. for-each advisors。遍历 advisors,筛选 IntroductionAdvisor。
    1. 如果 advisor instanceof IntroductionAdvisor 且满足 canApply 方法。
    2. 优先处理 IntroductionAdvisor,因为后续非 IntroductionAdvisor 的解析依赖 IntroductionAdvisor。
    3. 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)。
  2. for-each advisors。遍历 advisors,筛选非 IntroductionAdvisor。
    1. 如果
    2. canApply 方法签名是 org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Advisor, java.lang.Class, boolean)。

分支 canApply

方法

  1. org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Advisor, java.lang.Class, boolean)

流程

  1. if (advisor instanceof IntroductionAdvisor),then ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);。
  2. if (advisor instanceof PointcutAdvisor),then canApply(pca.getPointcut(), targetClass, hasIntroductions);。
    1. 方法:org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class, boolean)。
    2. 类级别判断 pc.getClassFilter().matches。
    3. 方法级别简略判断 (pc.getMethodMatcher() == MethodMatcher.TRUE)
    4. 方法级别详细判断。
      1. 如果目标类被代码,则获取其原始类。调用 org.springframework.util.ClassUtils#getUserClass(java.lang.Class)。
      2. 获取目标类的所有接口类。调用 org.springframework.util.ClassUtils#getAllInterfacesForClassAsSet(java.lang.Class)。
      3. for-each classes。遍历 classes,获取 class 中的所有方法,并校验是否匹配。
        1. 获取方法,包括子类与父类方法。调用 org.springframework.util.ReflectionUtils#getAllDeclaredMethods。
        2. for-each methods。遍历 methods,校验是否匹配。
          1. 如果满足 (methodMatcher instanceof IntroductionAwareMethodMatcher),则调用
          2. org.springframework.aop.IntroductionAwareMethodMatcher#matches。当前使用的 AspectJExpressionPointcut 是 IntroductionAwareMethodMatcher 的子类。
          3. 否则调用 org.springframework.aop.MethodMatcher#matches(java.lang.reflect.Method, java.lang.Class)。
  3. else true。
1
2
3
// org.springframework.aop.aspectj.AspectJExpressionPointcut
public class AspectJExpressionPointcut extends AbstractExpressionPointcut
		implements ClassFilter, IntroductionAwareMethodMatcher, BeanFactoryAware {}

分支 buildAdvisors

方法

  1. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#buildAdvisors

流程

  1. 方法:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#resolveInterceptorNames
  2. for-each allInterceptors
    1. 方法:org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#wrap。
    2. if (adviceObject instanceof Advisor), then (Advisor) adviceObject;
    3. if (advice instanceof MethodInterceptor), then new DefaultPointcutAdvisor
    4. for-each adapters
      1. if (adapter.supportsAdvice(advice)), then new DefaultPointcutAdvisor

END