Spring源码解析之AOP篇(四)----注册AnnotationAwareAspectJAutoProxyCreator的原因

摘要:上文解析了AnnotationAwareAspectJAutoProxyCreator的注册过程,但是我们却并没有分析注册它有何用?能在实现AOP功能的过程中起到什么作用,今天我就会详细分析!

一.注册AnnotationAwareAspectJAutoProxyCreator的原因

首先让我们先看下此类的继承和实现关系,我用的idea构建的。

不难看出,此类间接实现了BeanPostProcessor,那么此类也就拥有了拦截功能。话题从此处展开,先来解释下BeanPostProcessor的作用,那么真相自然而然便会浮出水面。

二.BeanPostProcessor的作用

请先看Spring官网的原话,看它是如何解释的。

有道翻译了一下,它说BeanPostProcessor算是一个容器的扩展点,对应AOP代理是必不可少的。所有说注册此Bean是必不可少的一步。那它在AOP代理中,主要做了什么事呢?我们先看下BeanPostProcessor的结构。

/**
*工厂挂钩,允许自定义修改新的bean实例,例如:检查标记接口或用代理包装它们。
*ApplicationContexts可以自动检测BeanPostProcessor中的bean,并将它们应用于随后创建的任何bean
**/
public interface BeanPostProcessor {

	//为在Bean的初始化前提供回调入口
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
	*在任何bean 之后,将这个BeanPostProcessor应用到给定的新bean实例
	*初始化回调(比如InitializingBean的{@code afterPropertiesSet})
	*或自定义init-方法)。bean已经被填充了属性值。
	*返回的bean实例可能是原始bean的包装器。
	**/
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

该类的功能为:通过在postProcessBeforeInitializationpostProcessAfterInitialization对传入的bean进行行为的自定义修改。这两个方法在什么时候会被调用到呢?类的注释说明的很清楚,ApplicationContext会自动检测BeanPostProcessor中的bean,并将它们应用于随后创建的bean。换句话说,在bean创建的过程中,这些扩展点会被调用。而在Spring创建bean的过程中,确实有这么一个调用过程,那就是AbstractAutowireCapableBeanFactory类中的initializeBean方法。

此处分别调用了BeanPostProcessor类中的beforeXXX和afterXXX。然后注入到IOC容器中。

//调用BeanPostProcessor后置处理器实例对象初始化之前的处理方法
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
		throws BeansException {
	Object result = existingBean;
	//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		//调用Bean实例所有的后置处理中的初始化前处理方法,为Bean实例对象在
		//初始化之前做一些自定义的处理操作
		Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

//调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		//调用Bean实例所有的后置处理中的初始化后处理方法,为Bean实例对象在
		//初始化之后做一些自定义的处理操作
		Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

那这个地方的BeanPostProcessor从哪来的呢?又是何时被创建的?

三.BeanPostProcessor实例何时被创建

先看看上面的getBeanPostProcessors()方法,到底做了什么?

public List<BeanPostProcessor> getBeanPostProcessors() {
	return this.beanPostProcessors;
}

/** BeanPostProcessors to apply in createBean. */
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();

这是直接取的成员变量的值,那难免好奇,这个list又是在哪初始化的呢?如果熟悉IOC容器初始化的同学应该都知道,BeanPostProcessor的初始化工作是在这里完成的。让我们一起看看源码。

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			postProcessBeanFactory(beanFactory);

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

			// 在此处完成向IOC容器注册BeanPostProcessor
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			initMessageSource();

			// Initialize event multicaster for this context.
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			onRefresh();

			// Check for listener beans and register them.
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			finishRefresh();
		}

		catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);
			}

			// Destroy already created singletons to avoid dangling resources.
			destroyBeans();

			// Reset 'active' flag.
			cancelRefresh(ex);

			// Propagate exception to caller.
			throw ex;
		}

		finally {
			// Reset common introspection caches in Spring's core, since we
			// might not ever need metadata for singleton beans anymore...
			resetCommonCaches();
		}
	}
}

这段代码在AbstractApplicationContext中,逻辑是非常清晰的,基本能看出来Spring是如何去完成IOC容器的初始化工作的。今天我们只关心后置处理器的初始化,其他的以后在单独写博客分析。让我们进入registerBeanPostProcessors(beanFactory)方法看看里面的逻辑。

public static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
	//根据类型获取到所有的BeanPostProcessor
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	// Register BeanPostProcessorChecker that logs an info message when
	// a bean is created during BeanPostProcessor instantiation, i.e. when
	// a bean is not eligible for getting processed by all BeanPostProcessors.
	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	// 区分并排序所有的BeanPostProcessor
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
	List<String> orderedPostProcessorNames = new ArrayList<>();
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		}
		else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// 先排序,然后再注册到IOC容器中
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

}

首先根据类型获取到所有的BeanPostProcessor,这一步早在扫描类路径的时候就已经拿到了所以需要被Spring托管的beanName。

从这里我们可以看到,拿到了4个beanName,这几个都是Spring内部的。这就包含了我们最开始创建的自动代理创建器。

private static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

	for (BeanPostProcessor postProcessor : postProcessors) {
		//此时开始添加
		beanFactory.addBeanPostProcessor(postProcessor);
	}
}

将这些后置处理器分别进行分类后排序,然后加入IOC容器中。

public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
	//先移除,防止重复添加
	this.beanPostProcessors.remove(beanPostProcessor);
	// Track whether it is instantiation/destruction aware
	if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
		this.hasInstantiationAwareBeanPostProcessors = true;
	}
	if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
		this.hasDestructionAwareBeanPostProcessors = true;
	}
	//此处将创建好的bean对象,加入list中,完成初始化工作
	this.beanPostProcessors.add(beanPostProcessor);
}

这里逻辑也比较简单,如果存在则先移除,然后再加入当前的list中。至此,list已经初始化完成。

总结

这一章节,带领大家揭开了注册AnnotationAwareAspectJAutoProxyCreator的原因,正因为当前这个类间接实现了BeanPostProcessor接口,那么它就具备了拦截器的功能,就能在bean创建的过程中对其进行增强,这也就为动态织入代码提供了可能性。下一篇文章,我会开始分析Spring是如何利用该类对象来为目标对象生成代理对象的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值