Spring中@Autowired注解装配流程

 众所周知,Autowired注解是通过AutowiredAnnotationBeanPostProcessor来实现的,不由得冒出几个问题,这个AutowiredAnnotationBeanPostProcessor哪来的,什么途径添加的,又是什么时候创建的,它在哪被执行?

第一个问题

注册AutowiredAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor在哪里注册的?

过程比较复杂,在使用xml和注解不同的场景中,略有不同,具体可以参考如下文章

# internalAutowiredAnnotationProcessor在哪冒出来的?

# AutowiredAnnotationBeanPostProcessor什么时候被实例化的?

只是注册了,只是在beanDefinitionMap中有了org.springframework.context.annotation.internalAutowiredAnnotationProcessor元素而已,还没创建成AutowiredAnnotationBeanPostProcessor对象

 此时的beanFactory的 singletonObjets中空空如也,也印证着确实没有AutowiredAnnotationBeanPostProcessor对象的存在

故而,引出第二个问题

实例化AutowiredAnnotationBeanPostProcessor

经过debug得知,AutowiredAnnotationBeanPostProcessor是在registerBeanPostProcessors(beanFactory)这一步实例化的

 看一下详细过程

registerBeanPostProcessors

	/**
	 * Instantiate and register all BeanPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before any instantiation of application beans.
	 */
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

代码上的注释明白的写着,实例化和注册所有的BeanPostProcessor

进去 registerBeanPostProcessors后,一上来就是getBeanNamesForType,把类型是BeanPostProcessor.class的bean的名称都从容器获取出来

可以看到postProcessorNames有三个元素,internalAutowiredAnnotationProcessor赫然在列

 拿到postProcessorNames后,循环遍历,进行getBean操作

BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);

里面有个小细节,getBean前还有一个if判断

if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) 

判断这个BeanPostProcessor是否是PriorityOrdered类型

 查看一下类图AutowiredAnnotationBeanPostProcessor,是实现了PriorityOrdered接口的

 所以能顺理成章的进入getBean环节,后面的就是熟悉的流程了,getBean调用doGetBean,doGetBean会先调用getSingleton(beanName)在容器中找一下,找到就返回,这里肯定是没有的

没找到就继续调用createBean,doCreateBean,

 然后调到createBeanInstance,instantiateBean

 跟踪到最后,发现是用java的发射方式,生成了一个对象返回的

 

 至此,AutowiredAnnotationBeanPostProcessor就被创建出来了

 如果要简短一点概括,就是在执行refresh方法的registerBeanPostProcessors方法中,进行实例化的。

然后AutowiredAnnotationBeanPostProcessor的实例化就完成了,然后就引出了第三个问题,在哪调用的?

实例化和初始化

要深刻理解@Autowired,需要先掌握一个前置知识,就是spring对象的完整创建过程分为两步,实例化和初始化,这个和jvm的实例化初始化稍有不同,spring中的实例化只的是“半成品”对象,里面的属性还未完成赋值,而初始化就可以理解为完整的对象,里面的所有属性都完成了赋值。

多提一嘴,正是因为有了分两步创建对象的策略,循环依赖问题才可以得以解决,这是后话,改天单独分析。

执行AutowiredAnnotationBeanPostProcessor

严格的来说不是执行AutowiredAnnotationBeanPostProcessor,而是执行AutowiredAnnotationBeanPostProcessor类中的postProcessMergedBeanDefinition方法

这个过程发生在bean的创建过程中,当bean完成了实例化(还未完成初始化)时,会执行一个叫applyMergedBeanDefinitionPostProcessors的方法,对@Autowired进行预解析

预解析

预解析就是,识别被@Autowired标注了的属性、构造方法、方法等,并将上面的注解元数据信息缓存起来

​编辑

我们可看到,这里循环调用的执行的是 MergedBeanDefinitionPostProcessor,咋一看这和我们的主角AutowiredAnnotationBeanPostProcessor毫无关系,怎么就会执行呢

这就要回到我们的 AutowiredAnnotationBeanPostProcessor类结构,可以看到不仅它实现了MergedBeanDefinitionPostProcessor接口,还实现了SmartInstantiationAwareBeanPostProcessor接口,所以这里是会执行的

写个小案例,Teacher中用@Autowired注入了Student

 可以看到,在Teacher完成了实例化,并未完成初始化时,student的值还是null

 值此“半成品”之际,applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)被执行,FactoryBean里面实现了MergedBeanDefinitionPostProcessor的BeanPostProcessor有多个,我们只关心AutowiredAnnotationBeanPostProcessor这个

 

 findAutowiringMetadata,查找Autowired元数据​编辑

 查找的细节就不深究了,总之,最终找到了student这个注解元数据,并且结果放到了injectionMetadataCache中。

 值此,预解析完成。

真正的解析

在完成与解析之后,我们的Teacher对象还只是完成了实例化,还没有完成初始化,需要调用populateBean 进行属性的填充,@Autowired真正的解析就发生在这里

populateBean

在populateBean中,主要是执行InstantiationAwareBeanPostProcessor的postProcessProperties方法进行属性的注入,和上面的一样,也是因为AutowiredAnnotationBeanPostProcessor间接的实现了InstantiationAwareBeanPostProcessor,所以才得以执行

 我们进去看看postProcessProperties方法

先从预解析步骤已经解析了并缓存了的缓存中取出注解元数据

 然后的核心就是

metadata.inject(bean, beanName, pvs);

从缓存中取出所有需要注入的 元素,这里只有一个student,调用element.inject

inject拿到student这个字段,检查是否已经处理过,没处理就要解析字段值

 resolveFieldValue的过程非常复杂,复杂到我目前还没有整明白

总之,通过resolveFieldValue,返回了student的对象

然后通过反射方式field.set(bean, value)将student设置给Teacher对象,完成了我们的注入

后续继续执行initializeBean等方法,Teacher就算真正的完成创建了。

总结

总结一下Spring中@Autowired注解装配的大体流程:

  1. 创建容器后都会通过AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)方法将一系列的internalXXXProcessor注册到容器,其中就包括internalAutowiredAnnotationProcessor
  2. 在执行registerBeanPostProcessors(beanFactory)时完成了AutowiredAnnotationBeanPostProcessor的创建与注册
  3. 在用户bean创建过程中(doCreateBean),实例化(createBeanInstance)之后,通过执行applyMergedBeanDefinitionPostProcessors方法,实现@Autowired注解元数据的预解析
  4. 在进行属性填充(populateBean)的过程中,通过调用InstantiationAwareBeanPostProcessor的postProcessProperties方法,在里面执行 inject 完成真正的注入

后续有空,在深入分析inject里面的逻辑,其中就包含经典面试题——autowired自动装配的两种方式:byName和byType的区别。

猜你喜欢

转载自juejin.im/post/7115705482504994829