AOP AbstractAutoProxyCreator 注册

警告
本文最后更新于 2020-11-29,文中内容可能已过时。

spring源码系列文章,示例代码的中文注释,均是 copy 自 https://gitee.com/wlizhi/spring-framework

链接中源码是作者从 github 下载,并以自身理解对核心流程及主要节点做了详细的中文注释。


1 AOP入口

AOP是通过 BeanPostProcessor.postProcessAfterInitialization() 实现的,来到 doCreateBean() -> initializeBean(),在初始化方法执行完成后,会调用 applyBeanPostProcessorsAfterInitialization(),这里循环调用了所有 BeanPostProcessor 的 postProcessAfterInitialization(),AOP 的入口就在其中的一个实现类,也是 AbstractAutoProxyCreator 的子类实现。

要看代理对象的生成过程,首先要看支持这个功能的类,是在哪里注册的,它源自哪里?

2 XMl配置方式BeanPostProcessor的注册

XMl方式注入AOP支持的BeanPostProcessor,是通过 <aop:aspectj-autoproxy/> 标签注入的。

根据SPI加载规则,找到 spring-aop 模块下的 META-INF/spring.handlers 文件。

可以看到以下内容:

1
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler

来到 AopNamespaceHandler 类,源码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public class AopNamespaceHandler extends NamespaceHandlerSupport {
	public void init() {
        registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        // AspectJAutoProxyBeanDefinitionParser标签 <aop:aspectj-autoproxy/> 的支持,
        // 在其 parse() 中注册了AOP的入口类 AnnotationAwareAspectJAutoProxyCreator,是一个 BeanPostProcessor
        registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
        registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
    }
}

我们在使用Spring XML配置方式使用 <aop:aspectj-autoproxy/> 标签激活代理,在 init() 中注册了 aspectj-autoproxy 属性的解析类,在这个解析类中,注入了 AnnotationAwareAspectJAutoProxyCreator 的 BeanDefinition。

源码如下:
步骤一:

1
2
3
4
5
6
7
8
9
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
    public BeanDefinition parse(Element element, ParserContext parserContext) {
		// 对aspectj-autoproxy属性的支持
		AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
		// 添加IncludePatterns
		extendBeanDefinition(element, parserContext);
		return null;
	}
}

步骤二:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public abstract class AopNamespaceUtils {
	public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			ParserContext parserContext, Element sourceElement) {
		// 这里注册了AnnotationAwareAspectJAutoProxyCreator
		BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
				parserContext.getRegistry(), parserContext.extractSource(sourceElement));
		useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
		registerComponentIfNecessary(beanDefinition, parserContext);
	}
}

步骤三:

1
2
3
4
5
6
7
8
public abstract class AopConfigUtils {
    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {
		// 注入此类 AnnotationAwareAspectJAutoProxyCreator,本质还是一个BeanPostProcessor,
		// 实现了BeanPostProcessor的子接口:SmartInstantiationAwareBeanPostProcessor
		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}
}

可以看到,步骤三中,最后 return 语句后注册了 AnnotationAwareAspectJAutoProxyCreator。

信息

回顾:BeanPostProcessor 提前注册到IOC容器的流程。

  1. 创建 BeanFactory,完成所有 BeanDefinition 的搜集。
  2. 执行 invokeBeanFactoryPostProcessors()(BeanDefinition的后置处理)。BeanFactoryPostProcessor 及子接口 BeanDefinitionRegistryPostProcessor 实现类的方法。
  3. 执行 registerBeanPostProcessors。从 beanFactory 中获取所有的 BeanPostProcessor,优先进行 getBean() 操作,实例化。

3 注解方式BeanPostProcessor的注册

3.1 注解方式案例

先看一个案例:

  1. 切面类:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Component  @Aspect  @Slf4j
public class CustomAspect {
	@Pointcut("execution(* top.wlz922.aspect.*.*(..))")
	public void pointCut(){}

	@Before("pointCut()")
	public void before(){
		log.info("CustomAspect.before execute...");
	}
}
  1. 业务类:
1
2
3
4
5
6
7
@Component
@Slf4j
public class Apple {
	public void showTaste(){
		log.info("Apple is sour and sweet.");
	}
}
  1. 配置类:
1
2
3
4
5
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "top.wlz922")
public class AspectAnoConfiguration {
}
  1. 测试类:
1
2
3
4
5
6
7
8
9
@Slf4j
public class ApplicationContextTest {
	@Test
	public void testAnoAop(){
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AspectAnoConfiguration.class);
		Apple apple = context.getBean(Apple.class);
		apple.showTaste();
	}
}

执行结果:

1
2
12:23:34.294 [main] INFO  top.wlz922.aspect.CustomAspect 16 - CustomAspect.before execute...
12:23:34.325 [main] INFO  top.wlz922.aspect.Apple 10 - Apple is sour and sweet.

以上是一个简单的注解方式激活AOP功能的案例。

3.2 AspectJAutoProxyRegistrar的注册

下面来看注解方式,注入对应支持的 BeanPostProcessor 的入口。

这是 @EnableAspectJAutoProxy 的声明:

1
2
3
4
5
6
7
8
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
	boolean proxyTargetClass() default false;
	boolean exposeProxy() default false;
}

可以看到,@EnableAspectJAutoProxy 上有一个 @Import,那么它在创建 BeanFactory,扫描注册 BeanDefinition 时,会把 AspectJAutoProxyRegistrar 类包装为 BeanDefinition 注册到容器中。

看 AspectJAutoProxyRegistrar 的声明:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		// TODO 注册自动代理的支持类的BeanDefinition到容器中。
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		// 如果激活了自动代理,这里会设置AnnotationAwareAspectJAutoProxyCreator的BeanDefinition对应的属性值
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}
}

来到 registerAspectJAnnotationAutoProxyCreatorIfNecessary():

1
2
3
4
5
6
7
8
9
public abstract class AopConfigUtils {
	@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {
		// 注入此类 AnnotationAwareAspectJAutoProxyCreator,本质还是一个BeanPostProcessor,
		// 实现了BeanPostProcessor的子接口:SmartInstantiationAwareBeanPostProcessor
		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}
}

可以看到,在这里对 AnnotationAwareAspectJAutoProxyCreator 进行了注册。

具体的注册逻辑源码(注意参数的传递):

 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
32
public abstract class AopConfigUtils {

    public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
			"org.springframework.aop.config.internalAutoProxyCreator";

	private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
		// 前面注册的类没用,注册不进来,这里会根据等级返回BeanDefinition,注解方式会返回AnnotationAwareAspectJAutoProxyCreator
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
				// 这里会有一个比较,在注册AbstractAdvisorAutoProxyCreator时,会有一个优先级。
				// 如果这里已经注册过AbstractAdvisorAutoProxyCreator,在此注册的时候,
				// 会与之前的注册的进行优先级比较,优先级高的会覆盖掉优先级低的。注解的优先级最高。
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}
		// 创建BeanDefinition,并设置一些属性。
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		// 注册到BeanDefinitionRegistry
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}
}

首先这里会判断容器中是否包含指定名称的 BeanDefinition,如果包含,拿这次将要注册的类型与已存在的类型进行优先级比对,以优先级高的为准进行 BeanDefinition 的注册。

看一下获取优先级的代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
public abstract class AopConfigUtils {
	private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);

	static {
		// 这里默认包含三个代理生成类
		// Set up the escalation list...
		APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
	}

    private static int findPriorityForClass(@Nullable String className) {
		for (int i = 0; i < APC_PRIORITY_LIST.size(); i++) {
			Class<?> clazz = APC_PRIORITY_LIST.get(i);
			if (clazz.getName().equals(className)) {
				return i;
			}
		}
		throw new IllegalArgumentException(
				"Class name [" + className + "] is not a known auto-proxy creator class");
	}
}

在 AopConfigUtils 静态代码块中,初始化了三个 BeanPostProcessor 的实现,按照在 list 容器中的索引大小来确定优先级。优先级大小顺序为:

AnnotationAwareAspectJAutoProxyCreator > AspectJAwareAdvisorAutoProxyCreator > InfrastructureAdvisorAutoProxyCreator