zoukankan      html  css  js  c++  java
  • 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 中Timer和TimerTask 定时器和定时任务使用的例子详解
    CentOS7下安装Scrapy步骤详解
    使用C++实现求最大公约数和最小公倍数算法详解
    windows ruby on rails搭建搭建
    php爬虫选择器-来自phpspider
    markdown增强显示插件
    PHP7以上的异常处理变化
    open-php开源项目:php-code-generator PHP流行框架的curd的代码生成器
    laravel withoutOverlapping导致执行脚本延迟或者失效问题
    vcpkg国内镜像设置
  • 原文地址:https://www.cnblogs.com/juniorMa/p/14317242.html
Copyright © 2011-2022 走看看