spring-aop源码分析(1)_AnnotationAwareAspectJAutoProxyCreator的引入

37 篇文章 0 订阅
31 篇文章 2 订阅

本系列文章将从@EnableAspectJAutoProxy注解入手分析spring aop的核心原理:

  • 使用@EnableAspectJAutoProxy注解的效果
  • AnnotationAwareAspectJAutoProxyCreator后置处理器的引入
  • AnnotationAwareAspectJAutoProxyCreator匹配切入点、创建通知、创建bean代理的原理
  • AOP通知的执行原理

本系列文章基于spring.5.2.12.RELEASE版本,springboot使用的应该是org.springframework.boot.autoconfigure.aop.AopAutoConfiguration自动装配方式,本文暂不讨论,原理上也是一样的。

本文将从@EnableAspectJAutoProxy注解,看一下AnnotationAwareAspectJAutoProxyCreator后置处理器是如何注入到spring中的。

@EnableAspectJAutoProxy注解

spring aop是通过@EnableAspectJAutoProxy注解开启的,我们先看一下使用该注解前后spring容器的区别。

使用前:
在这里插入图片描述

使用后:
在这里插入图片描述

可以看到使用@EnableAspectJAutoProxy注解之后spring多注入了一个叫做AnnotationAwareAspectJAutoProxyCreator的beanPostProcessor处理器。

本文就将分析这个后置处理器是如何注入到spring容器的。

AspectJAutoProxyRegistrar注册AnnotationAwareAspectJAutoProxyCreator后置处理器

我们看一下@EnableAspectJAutoProxy注解的源码,他import了一个AspectJAutoProxyRegistrar组件:

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	/**
	 * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
	 * to standard Java interface-based proxies.
	 */
	boolean proxyTargetClass() default false;

	/**
	 * Indicate that the proxy should be exposed by the AOP framework as a ThreadLocal
	 * for retrieval via the AopContext class.
	 */
	boolean exposeProxy() default false;

AspectJAutoProxyRegistrar将向容器中注入AnnotationAwareAspectJAutoProxyCreator后置处理器:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        // 注入AnnotationAwareAspectJAutoProxyCreator
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		// other code
	}
}

那么这个方法是什么时候调用的?

debug一下可以发现几个比较重要的方法:
在这里插入图片描述

上方的红框标注的方法在ConfigurationClassPostProcessor类,用于从config配置类解析出bean definition并将其注册到容器。

下方的红框标注的方法在AbstractApplicationContext类,用于调用BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor处理器。

invokeBeanFactoryPostProcessors方法

AbstractApplicationContext的refresh方法

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {

		prepareRefresh();

		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		prepareBeanFactory(beanFactory);

		try {
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			registerBeanPostProcessors(beanFactory);

invokeBeanFactoryPostProcessors方法

Instantiate and invoke all registered BeanFactoryPostProcessor beans, respecting explicit order if given. Must be called before singleton instantiation.

实例化并调用所有注册的BeanFactoryPostProcessor bean,如果指定顺序,则遵循显式顺序。必须在单例实例化之前调用。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate
        .invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

	// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime.
}

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法中会先调用所有的BeanDefinitionRegistryPostProcessor处理器:

// currentRegistryProcessors是一个BeanDefinitionRegistryPostProcessor集
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

此时里面只有一个ConfigurationClassPostProcessor处理器,他是在容器初始化最开始时注册的,暂时不做分析。

看一下invokeBeanDefinitionRegistryPostProcessors方法:

/**
 * Invoke the given BeanDefinitionRegistryPostProcessor beans.
 */
private static void invokeBeanDefinitionRegistryPostProcessors(
    Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors,
    BeanDefinitionRegistry registry) {

	for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
		postProcessor.postProcessBeanDefinitionRegistry(registry);
	}
}

ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry实现

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
	processConfigBeanDefinitions(registry);
}

processConfigBeanDefinitions中有这样一段逻辑:

  • 使用ConfigurationClassParser从容器里面解析configurationModel集
  • 然后从configurationModel集解析import的bean definition

解析config配置类

// ...

// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
		this.metadataReaderFactory, this.problemReporter, this.environment,
		this.resourceLoader, this.componentScanBeanNameGenerator, registry);

Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());

do {
	parser.parse(candidates);
	parser.validate();

    // 解析出configurationModel集
	Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
	configClasses.removeAll(alreadyParsed);

	// Read the model and create bean definitions based on its content
	if (this.reader == null) {
		this.reader = new ConfigurationClassBeanDefinitionReader(
				registry, this.sourceExtractor, this.resourceLoader, this.environment,
				this.importBeanNameGenerator, parser.getImportRegistry());
	}
    
    // 解析import的beanDefinition
	this.reader.loadBeanDefinitions(configClasses);
	alreadyParsed.addAll(configClasses);

// ...

parser.parse(candidates)中有解析配置类导入ImportBeanDefinitionRegistrar的逻辑:

protected void processConfigurationClass(
    ConfigurationClass configClass, Predicate<String> filter) throws IOException {
	// 省略

	SourceClass sourceClass = asSourceClass(configClass, filter);
	do {
        // 解析配置类
		sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
	}
	while (sourceClass != null);

	this.configurationClasses.put(configClass, configClass);
}

// 中间代码省略,只记录重要的内容

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
		Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
		boolean checkForCircularImports) {

	// 省略

	if (checkForCircularImports && isChainedImportOnStack(configClass)) {
		this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
	}
	else {
		this.importStack.push(configClass);
		try {
			for (SourceClass candidate : importCandidates) {
				if (candidate.isAssignable(ImportSelector.class)) {
					// 省略
				}
				else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
                    // 这个分支解析ImportBeanDefinitionRegistrar
					// Candidate class is an ImportBeanDefinitionRegistrar ->
					// delegate to it to register additional bean definitions

                    // 在本例中,解析出来的是AspectJAutoProxyRegistrar类
					Class<?> candidateClass = candidate.loadClass();
                    // 这里就是把AspectJAutoProxyRegistrar实例化
					ImportBeanDefinitionRegistrar registrar = ParserStrategyUtils
                        		.instantiateClass(candidateClass,
                                                  ImportBeanDefinitionRegistrar.class,
									              this.environment,
                                                  this.resourceLoader,
                                                  this.registry);
					// 添加configClass里面以便后续使用
                    configClass
                        .addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
				}
				else {
					// 省略
				}
			}
		}
	}
}

reader.loadBeanDefinitions(configClasses)

private void loadBeanDefinitionsForConfigurationClass(
		ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

    // 判断配置是否跳过
	if (trackedConditionEvaluator.shouldSkip(configClass)) {
		String beanName = configClass.getBeanName();
		if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
			this.registry.removeBeanDefinition(beanName);
		}
		this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
		return;
	}

	if (configClass.isImported()) {
		registerBeanDefinitionForImportedConfigurationClass(configClass);
	}
	for (BeanMethod beanMethod : configClass.getBeanMethods()) {
		loadBeanDefinitionsForBeanMethod(beanMethod);
	}

	loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
    // 从ImportBeanDefinitionRegistrar导入BeanDefinition
    // configClass的importBeanDefinitionRegistrars已经在之前的逻辑中介绍了
	loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}

private void loadBeanDefinitionsFromRegistrars(
    Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
    // 在此处就调用了AspectJAutoProxyRegistrar的registerBeanDefinitions方法
	registrars.forEach((registrar, metadata) ->
			registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));
}

到此就已经把AnnotationAwareAspectJAutoProxyCreator后置处理器注册到了spring容器的BeanDefinition中。

后续还需要把BeanPostProcessor从BeanDefinition中找出来,实例化并添加到beanPostProcessors集,以便后续使用。

registerBeanPostProcessors方法

这个方法很简单,就是将容器里面的BeanPostProcessor找出来,做优先级匹配、排序等,然后进行初始化,注入到容器里面。

代码就不记录了。

下一篇文章将介绍AnnotationAwareAspectJAutoProxyCreator的工作:

  • 切入点的匹配
  • 通知创建
  • 代理创建
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值