• Spring 之@Value注解原理


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

      会调用 AutoWiredAnnotationBeanPostProcessor.postProcessPropertyValues

    public PropertyValues postProcessPropertyValues(
                PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
    
            InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
         
    //findAutowiringMetadata表示找到该bean中所有的@Value和@Autowired注解,然后组成InjectionMetadata
    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;
        }

    metadata.inject还是会遍历处理每一个 AutowiredFieldElement 或者 AutowiredMethodElement

    protected void inject(Object bean, String beanName, 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<String>(1);
                    TypeConverter typeConverter = beanFactory.getTypeConverter();
                    try {
                        value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                    }
                    catch (BeansException ex) {
                        throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
                    }

      继续

      DefaultListableBeanFactory.resolveDependency

    public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
                Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
    
            descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
            if (javaUtilOptionalClass == descriptor.getDependencyType()) {
                return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
            }
            else if (ObjectFactory.class == descriptor.getDependencyType() ||
                    ObjectProvider.class == descriptor.getDependencyType()) {
                return new DependencyObjectProvider(descriptor, requestingBeanName);
            }
            else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
                return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
            }
            else {
                Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
                        descriptor, requestingBeanName);
                if (result == null) {
                    result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
                }
                return result;
            }
        }

      

    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();
                Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);//${driverClassName}
                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;
            for (StringValueResolver resolver : this.embeddedValueResolvers) {//[org.springframework.beans.factory.config.PropertyPlaceholderConfigurer$PlaceholderResolvingStringValueResolver@17d88132]
                result = resolver.resolveStringValue(result);//这里就取到了真实的值
                if (result == null) {
                    return null;
                }
            }
            return result;
        }

    总结

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

    @Component
    public class CommonPo {
        
        @Value("${driverClassName}")
        private String driver;

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

      

  • 相关阅读:
    java线程的几种状态
    java事务的处理
    Java多线程中Sleep与Wait的区别
    分享一百多套开发视频教程的下载地址
    [Java]读取文件方法大全
    Android开发人员必备的10 个开发工具
    CentOS 安装MySQL rpm方式安装
    记录一些经典的算法
    CentOS 7安装Redis服务
    linux查看文件大小,磁盘占用情况 du df命令
  • 原文地址:https://www.cnblogs.com/juniorMa/p/14317242.html
Copyright © 2020-2023  润新知