Spring @Autowired注解的实现原理
1、@Autowired注解是如何实现自动装配的?
2、当为类型为OrderService的Bean装配类型为UserService的属性时,如果此时Spring容器中存在多个类型为UserService的bean,此时Spring是如何处理的?
3、自动装配的模型是什么?有哪几种?和Autowired注解有什么关联?
@Autowired
自动装配是通过后置处理器来完成的。这个后置处理器就是 AutowiredAnnotationBeanPostProcessor
要解决上面说的问题,就要了解 Spring Bean生命周期 以及 @AutoWirte的原理,这块需要看对应的源码
@Autowirte如何实现自动装配
// TODO 流程图
@Autowirte自动装配源码详解
@Autowired
自动装配是通过AutowiredAnnotationBeanPostProcessor这个后置处理器来完成的。具体是怎么实现的呢?
1、在容器启动前会注册内置AutowiredAnnotationBeanPostProcessor
后置处理器
2、在容器启动时refresh()时,调用 registerBeanPostProcessors(beanFactory)
方法获取并把AutowiredAnnotationBeanPostProcessor
注册到beanFactory里
3、在创建bean执行到populateBean方法会调用AutowiredAnnotationBeanPostProcessor
的postProcessProperties
方法,在这个方法里会解析出带有@Autowired注解、@Inject和@Value的属性和方法,通过反射完成注入。
(2.1) 容器启动前注册内置BeanPostProcessor
当我们调用AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class)启动容器的时候,在构造方法中会调用到this()方法,
在this()方法中最终会调用 AnnotationConfigUtils 的 registerAnnotationConfigProcessors(BeanDefinitionRegistry) 方法,在该方法中,Spring会向容器注册7个Spring内置的Bean,其中就包括AutowiredAnnotationBeanPostProcessor。
/**
* Register all relevant annotation post processors in the given registry.
* @param registry the registry to operate on
* @param source the configuration source element (already extracted)
* that this registration was triggered from. May be {@code null}.
* @return a Set of BeanDefinitionHolders, containing all bean definitions
* that have actually been registered by this call
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 省略部分代码...
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 注册 AutowiredAnnotationBeanPostProcessor,这个bean的后置处理器用来处理@Autowired的注入
// 处理 @Autowired 以及 @Value 注解
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册CommonAnnotationBeanPostProcessor,用来处理如@Resource等符合JSR-250规范的注解
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 省略部分代码
return beanDefs;
}
在这个方法中可以看到会注册 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 两个处理器
然后在 Spring 应用上下文刷新阶段会将其初始化并添加至 AbstractBeanFactory 的 beanPostProcessors 集合中
当一个 Bean 被构建时,核心包括两个基本步骤:
1、执行 AbstractAutowireCapableBeanFactory#createBeanInstance 方法:通过构造器反射构造出这个 Bean
2、执行 AbstractAutowireCapableBeanFactory#populate 方法:填充(即设置)这个 Bean
// Invoke factory processors registered as beans in the context.
AbstractApplicationContext::refresh()
AbstractAutowireCapableBeanFactory::doCreateBean()
populateBean()
在构建appConfig bean时会走到 populateBean方法
/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw the BeanWrapper with bean instance
*/
@SuppressWarnings("deprecation") // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//省略部分非关键代码
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 执行后置处理器,填充属性,完成自动装配
// 在这里会调用到AutowiredAnnotationBeanPostProcessor
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
//省略部分非关键代码
}
因为 StudentController 含有标记为 Autowired 的成员属性 dataService,所以会使用到 AutowiredAnnotationBeanPostProcessor(BeanPostProcessor 中的一种)来完成“装配”过程:找出合适的 DataService 的 bean 并设置给 StudentController#dataService。
这个装配过程,又可以细分为两个步骤:
1、AutowiredAnnotationBeanPostProcessor::postProcessProperties
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
// 解析出bean中带有@Autowired注解、@Inject和@Value注解的属性和方法
// 对于本文的demo而言,在此处就会解析出OrderServiceImpl类上的userService属性
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 自动装配,实现依赖注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
2、根据依赖信息寻找出依赖并完成注入,以字段注入为例 AutowiredFieldElement#inject
备注 AutowiredFieldElement 是 AutowiredAnnotationBeanPostProcessor 的一个内部类
@Override
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 寻找“依赖”,desc为"xxxService"的DependencyDescriptor
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
}
}
参考
[1] @Autowired注解的实现原理
[2] 死磕Spring之IoC篇 - @Autowired 等注解的实现原理
[3] 02|Spring Bean 依赖注入常见错误(上)