@Value和@Autowired这两个注解都是由AutowiredAnnotationBeanPostProcessor
来处理的,这两个注解被处理的地方也是一样的,就是在一个bean被new出来之后,要填充属性的populateBean方法里。会调用 AutoWiredAnnotationBeanPostProcessor.postProcessPropertyValues
。不同的地方就是处理的逻辑
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
//${driverClassName}
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
// 解析占位符号
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
解析占位符
public String resolveEmbeddedValue(String value) {
if (value == null) {
return null;
}
String result = value;
//[org.springframework.beans.factory.config.
// PropertyPlaceholderConfigurer$PlaceholderResolvingStringValueResolver@17d88132]
for (StringValueResolver resolver : this.embeddedValueResolvers) {
//这里就取到了真实的值
result = resolver.resolveStringValue(result);
if (result == null) {
return null;
}
}
return result;
}
总结
如果一个bean里面的某个字段有注释@Value
@Component
public class CommonPo {
@Value("${driverClassName}")
private String driver;
注释的值如果是默认的占位符标志,就会调用 PropertyPlaceholderConfigurer
里的方法获取配置文件里的值