@Autowired 的实现原理 ?

一、@Autowired 的实现原理

实现 @Autowired 的关键是:AutowiredAnnotationBeanPostProcessor


在 Bean 的初始化阶段,会通过 Bean 后置处理器来进行一些前置和后置的处理。实现 @Autowired 的功能,也是通过后置处理器来完成的。这个后置处理器就是 AutowiredAnnotationBeanPostProcessor。


1、Spring在创建 bean的过程中,最终会调用到 doCreateBean()方法,在 doCreateBean()方法 中会调用 populateBean()方法,来为 bean 进行属性赋值,完成自动装配等工作。


2、在 populateBean()方法中一共调用了两次后置处理器,第一次是为了判断是否需要属性填充,如果不需要进行属性充,那么就会直接进行return,如果需要进行属性填充,那么方法就会继续向下执行,后面会进行第二次后

置处理器的调用,这个时候,就会调用到 AutowiredAnnotationBeanPostProcessor 的 postProcessPropertyValues()方法,在该方法中就会进行@Autowired 注解的解析,然后实现自动装配。


二、源码分析


1、首先点开 @Autowired,注释上写Please consult the javadoc for the AutowiredAnnotationBeanPostProcessor,让我们去查阅这个类,看一下这个类的继承关系树,如下:

可见它间接实现InstantiationAwareBeanPostProcessor,就具备了实例化前后【而不是初始化前后】管理对象的能力,实现了BeanPostProcessor,具有初始化前后管理对象的能力,实现 BeanFactoryAware,

具备随时拿到 BeanFactory 的能力,也就是说,这个 AutowiredAnnotationBeanPostProcessor 具备一切后置处理器的能力


1、容器在初始化的时候,后置处理器的初始化要优先于剩下自定义Bean【比如我们自定义的Service,Controller等等】的初始化的,我们自定义的Bean初始化是在 finishBeanFactoryInitialization(beanFactory) 这里完成的,

来到 AbstractApplicationContext的refresh()方法。


2、finishBeanFactoryInitialization(beanFactory)-->beanFactory.preInstantiateSingletons()-->getBean(beanName)-->doGetBean(beanName)-->来到AbstractBeanFactory第317行createBean(beanName, mbd, args),


来创建bean实例-->来到AbstractAutowireCapableBeanFactory第503行doCreateBean(beanName, mbdToUse, args)-->紧接着来到AbstractAutowireCapableBeanFactory的第543行,


instanceWrapper = createBeanInstance(beanName, mbd, args)就已经把Bean实例创建出来了,只不过instanceWrapper是一个被包装过了的bean,


它里面的属性还未赋实际值-->然后来到第555行applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName),这一步的作用就是将所有的后置处理器拿出来,


并且把名字叫beanName的类中的变量都封装到InjectionMetadata的injectedElements集合里面,目的是以后从中获取,挨个创建实例,通过反射注入到相应类中


3、紧接着来到 AbstractAutowireCapableBeanFactory 第588行 populateBean(beanName, mbd, instanceWrapper) --> 点进去,来到AbstractAutowireCapableBeanFactory的第1347行,来循环遍历所有的后置处理器


for (BeanPostProcessor bp : getBeanPostProcessors()),从方法名字postProcessPropertyValues也能看出来,就是给属性赋值,当bp是AutowiredAnnotationBeanPostProcessor的时候,


进入postProcessPropertyValues方法,来到AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues方法,如下:

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {

	//@Autowired注解、@Inject和@Value注解的属性和方法
	InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

	try {
		//属性填充
		metadata.inject(bean, beanName, pvs);
		return pvs;
	} catch (BeanCreationException var6){ 
		throw var6;
	} catch (Throwable var7) {
		throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
	}
}

首先找到需要注入的哪些元数据,然后metadata.inject(注入),注入方法点进去,来到 InjectionMetadata的inject方法,在一个for循环里面依次执行 element.inject(target, beanName, pvs),来对属性进行注入。

  进入element.inject(target, beanName, pvs),注意,这里必须要debug才可以进入真正的方法。来到 AutowiredAnnotationBeanPostProcessor的inject方法,


第584行,value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter),由工厂解析这个依赖,进入,来到DefaultListableBeanFactory第1065行,


result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter)再次解析依赖,点击进入,来到DefaultListableBeanFactory的doResolveDependency()方法,前面是一堆判断,


比较,查看属性类型,这种类型的有几个(matchingBeans),如果只有一个匹配,那么来到第1138行,instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this),进入这个方法,


可以看到就是前面说的根据工厂来创建实例的过程了:beanFactory.getBean(beanName),其中这个beanName就是属性的名称,当经过一系列操作完成属性的实例化后,便来到AutowiredAnnotationBeanPostProcessor的第611行,


利用反射为此对象赋值。这样,对象的创建以及赋值就完成了。


三、总结


在容器启动,容器自动装载了一个 AutowiredAnnotationBeanPostProcessor 后置处理器,在对象赋值的时候,

遇到@Autowired注解,会用后置处理器机制,来创建属性的实例,然后再利用反射机制,将实例化好的属性,

赋值给对象上,这就是 @Autowired 的原理

posted @ 2024-11-01 21:06  jock_javaEE  阅读(120)  评论(0)    收藏  举报