@Value和@Autowired这两个注解都是由AutowiredAnnotationBeanPostProcessor来处理的,这两个注解被处理的地方也是一样的,就是在一个bean被new出来之后,要填充属性的populateBean方法里。会调用 AutoWiredAnnotationBeanPostProcessor.postProcessPropertyValues。不同的地方就是处理的逻辑

    1. public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
    2. Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
    3. InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
    4. try {
    5. Object shortcut = descriptor.resolveShortcut(this);
    6. if (shortcut != null) {
    7. return shortcut;
    8. }
    9. Class<?> type = descriptor.getDependencyType();
    10. //${driverClassName}
    11. Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
    12. if (value != null) {
    13. if (value instanceof String) {
    14. // 解析占位符号
    15. String strVal = resolveEmbeddedValue((String) value);
    16. BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
    17. value = evaluateBeanDefinitionString(strVal, bd);
    18. }
    19. TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
    20. return (descriptor.getField() != null ?
    21. converter.convertIfNecessary(value, type, descriptor.getField()) :
    22. converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
    23. }

    解析占位符

    1. public String resolveEmbeddedValue(String value) {
    2. if (value == null) {
    3. return null;
    4. }
    5. String result = value;
    6. //[org.springframework.beans.factory.config.
    7. // PropertyPlaceholderConfigurer$PlaceholderResolvingStringValueResolver@17d88132]
    8. for (StringValueResolver resolver : this.embeddedValueResolvers) {
    9. //这里就取到了真实的值
    10. result = resolver.resolveStringValue(result);
    11. if (result == null) {
    12. return null;
    13. }
    14. }
    15. return result;
    16. }

    总结
    如果一个bean里面的某个字段有注释@Value

    1. @Component
    2. public class CommonPo {
    3. @Value("${driverClassName}")
    4. private String driver;

    注释的值如果是默认的占位符标志,就会调用 PropertyPlaceholderConfigurer 里的方法获取配置文件里的值