Spring中AOP源码浅析②

本文深入探讨了Spring AOP中后置处理器的加载和初始化过程,从BeanPostProcessor的注册到业务Bean的实例化。在refresh()方法中,通过registerBeanPostProcessors()和finishBeanFactoryInitialization()进行处理器加载。分析了创建Bean的过程,特别是在doGetBean()和createBean()方法中,后置处理器有机会返回代理对象。InstantiationAwareBeanPostProcessors在Bean实例化前发挥作用,特别是AnnotationAwareAspectJAutoProxyCreator,它在Bean生命周期中的作用将在后续文章中进一步讨论。
摘要由CSDN通过智能技术生成

上一篇文章Spring中AOP源码浅析①讲到AOP中实际是通过BeanPostProcesser后置处理器实现的。后置处理器就是在Bean初始化前后进行拦截调用。

那么我们的后置处理器是如何加载和初始化呢?(后置处理器是一类特殊的Bean)

猜想一下,肯定是在普通单例Bean之前进行加载和初始化操作,只有先加载了处理器才能通过处理器去拦截Bean。

那么我们就从业务Bean的加载这一步看源码是如何实现的,实际业务Bean和处理器Bean加载过程类似。还是使用Spring中AOP的使用这篇文章的代码运行调试。(测试类、配置类MainConfig、业务类Fun、切面类LogAspect并且加上相应注解)

第一步Spring容器通过配置类创建Ioc容器:

AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);

配置类在这篇文章有提到聊一聊SpringBean的生命周期——创建、初始化、销毁。

点进去AnnotationConfigApplicationContext 这个类查看

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		this();
        //注册配置类
		register(annotatedClasses);
        //刷新Spring容器上下文
		refresh();
	}

处理器和Bean的加载初始化过程就在这个refresh()方法里,点进去

...
@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 {
            ...

			// Register bean processors that intercept bean creation.
            //注册拦截Bean创建的后置处理器
			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.
            //实例化所有剩余非懒加载单例Bean
			finishBeanFactoryInitialization(beanFactory);

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

从源码看拦截的后置处理器的加载是比非懒加载单例Bean要早的。分别是registerBeanPostProcessors(beanFactory),finishBeanFactoryInitialization(beanFactory)这两个方法。

跟进registerBeanPostProcessors(beanFactory)继续看,发现是调用了PostProcessorRegistrationDelegate委托类的registerBeanPostProcessors()方法。

	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        ....
        //区分操作,分离出实现PriorityOrdered接口、Ordered接口和剩余的后置处理器并放入List
		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);
			}
		}
        ....

        //1、首先注册实现PriorityOrdered接口的后置处理器
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		//2、接下来注册实现Ordered接口的后置处理器
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		//3、现在注册所有普通的后置处理器
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);


        //4、最后 重新注册所有内部后置处理器
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		....
	}

现在看来后置处理器的加载顺序也很清楚了:

  1. 注册实现PriorityOrdered接口的后置处理器
  2. 注册实现Ordered接口的后置处理器
  3. 注册所有普通的后置处理器
  4. 重新注册所有内部后置处理器

在这里介绍一下这两个优先级的接口,PriorityOrdered继承自Ordered,两个接口都通过getOrder()判断优先级。

我们在分离出List这一步之后打个断点,看一下四个List容器里面分别放了哪几个后置处理器。

发现涉及AOP的处理器(org.springframework.aop.config.internalAutoProxyCreator)在 orderedPostProcessorNames 这里,这说明这个后置处理器是需要优先加载的。在以上分析的第二步注册

refresh()中的注册拦截Bean创建的后置处理器registerBeanPostProcessors(beanFactory)方法执行完毕后,我们再来看下实例化所有剩余非懒加载单例Bean方法finishBeanFactoryInitialization(beanFactory)的执行过程。

执行了beanFactory.preInstantiateSingletons() 点进去看,执行到这一步发现会遍历所有的BeanName(包含了处理器和业务Bean),之后调用了getBean(beanName),里面调用doGetBean(name, null, null, false)。这里发现我们的普通业务Bean和后置处理器都会进入到doGetBean()方法,这说明Bean的实例化的过程是一致的。

那么我们就直接看增强代码是如何加入到业务Bean的。在doGetBean()这一步仔细看一下代码,找到创建单例Bean的步骤,也可以加断点debug。

	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// 检查缓存中是否存在
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
...

这一步会先拿缓存,若没有才会实例化。缓存和我们的工厂一样,实际都是一个Map对象。

	/** Cache of singleton objects: bean name --> bean instance */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/** Cache of singleton factories: bean name --> ObjectFactory */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/** Cache of early singleton objects: bean name --> bean instance */
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

在doGetBean()这一步查看,

...
	// Create bean instance.
    // 创建Bean实例
	if (mbd.isSingleton()) {    //Bean的定义为单例
		sharedInstance = getSingleton(beanName, () -> {
			try {
				return createBean(beanName, mbd, args);
			}
			catch (BeansException ex) {
				// Explicitly remove instance from singleton cache: It might have been put there
				// eagerly by the creation process, to allow for circular reference resolution.
				// Also remove any beans that received a temporary reference to the bean.
				destroySingleton(beanName);
				throw ex;
			}
		});
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
	}
......

看代码推测这一步是创建单例Bean实例的步骤,可以在这打个断点debug,进入createBean(beanName, mbd, args);方法。

现在只关注我们的业务Bean,其他处理器则可以跳过。

createBean这里面前面都是一些解析判断准备工作。debug执行到了这里,给后置处理器一个机会去返回代理对象而不是目标Bean实例。推测这里会有后置处理器 执行相关的代码。

...
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//给后置处理器一个返回代理对象的机会而不是目标Bean实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
		return bean;
}
...

但是执行完毕之后 bean=null ,并没有出现预想的结果。

注释翻译:给后置处理器一个返回代理对象的机会而不是目标Bean实例

该方法翻译:实例化前解析

再次运行,进入到方法体内部。

	/**
	 * Apply before-instantiation post-processors, resolving whether there is a
	 * before-instantiation shortcut for the specified bean.
	 * 请求实例化之前的后置处理器,以解析指定的bean是否存在实例化之前的快捷方式。
	 */
	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.确保此时已经解析了该类
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

这里出现了InstantiationAwareBeanPostProcessors后置处理器,那么就和我们之前提到的AnnotationAwareAspectJAutoProxyCreator(Bean名称:internalAutoProxyCreator 对应到了,因为后者实际就是前者的实现。设想AOP相关的这个后置处理器应该会在这里执行。进入 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);

	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        //遍历所有后置处理器
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
            //得到InstantiationAwareBeanPostProcessor相关的这个后置处理器
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                //执行前置方法
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

发现确实在这里执行了相应的前置处理方法。这里应该是由InstantiationAwareBeanPostProcessor相关的这个后置处理器去执行前置方(internalAutoProxyCreator)。

resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)

继续向下执行,进入到这个方法。(因为这句代码执行完毕后有日志打印:完成创建Bean实例

....
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
	logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
....

进去之后发现是要封装一个BeanWrapper对象。

...
// Initialize the bean instance.
Object exposedObject = bean;
try {
    //属性赋值
	populateBean(beanName, mbd, instanceWrapper);
	exposedObject = initializeBean(beanName, exposedObject, mbd);
...

这一句执行完之后在debugger窗口发现exposedObject 变成了一个代理对象

之后继续往后执行就返回了。所以肯定是initializeBean(beanName, exposedObject, mbd);这一步执行了相应的方法创建的业务Bean。

点击源代码进去:

	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
            //执行相关感知接口方法注入组件
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            //执行后置处理器相关前置方法
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
            //执行初始化方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
            //执行后置处理器相关后置方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

这里就很清楚了,主要做了四件事:

  1. 执行Aware接口方法
  2. 执行后置处理器前置方法
  3. 执行初始化方法
  4. 执行后置处理器后置方法

所以代理的创建过程一定是在后置处理器的执行过程中,刚才调试过程中初始化后置操作执行完之后才返回的业务代理对象。所以一定是某个后置处理器(BeanPostProcessor)的后置方法执行完之后才创建的代理对象。

在上篇文章Spring中AOP源码浅析①讲到AnnotationAwareAspectJAutoProxyCreator实际是一个后置处理器(SmartInstantiationAwareBeanPostProcessor 继承InstantiationAwareBeanPostProcessor),所以我们只要看后置处理器的执行代码就知道具体的Bean生成过程。

不管我们的Bean如何改变都脱离不了以上的过程。画个图总结一下

AnnotationAwareAspectJAutoProxyCreator 这个AOP处理器具体的前置、后置创建代理的过程下一篇文章再聊。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值