Spring启动过程分析.番外(@Value)

这篇文章我们来分析一下经过@Value注释的变量时如何注入属性值的。

@Value属性值的注入发生在调用populateBean给实例化完成的bean填充属性之时。

遍历BeanPostProcessor列表,当调用AutowiredAnnotationBeanPostProcesorpostProcessPropertyValues方法时:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
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;
}

可以看到,首先调用findAutowiringMetadata函数来找到需要注入的元数据,然后调用inject方法来注入相应的属性值。

InjectMetadata.inject(Object target, String beanName, PropertyValues pvs)

inject方法中遍历InjectedElement元素,调用AutowiredFieldElement.inject方法:

  1. 调用value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter)解析表达式
  2. 调用field.set(bean, value)将解析的值设置到相应的字段中

DefaultListableBeanFactory.resolveDependency

该方法针对bean定义解析特定的依赖,它最终调用的是DefaultListableBeanFactory.doResolveDependency方法:

  1. 调用AutowireCandidateResolver.getSuggestedValue(descriptor)获得@Value注释中的描述信息。
  2. 如果这个描述信息非null且是String类型,调用resolveEmbeddedValue来解析描述信息的值。默认情况下调用AbstractPropertyResolver.resolvePlaceholders来解析这个表达式
  3. 根据需要转换的类型,将解析表达式获得的值转换成响应的类型