zoukankan      html  css  js  c++  java
  • Spring @Value 配置项解析 vs Spring @ConfigurationProperties 配置项解析

    @ConfigurationProperties 的属性注入是在 initializeBean() 的时候处理的,即 populateBean() 之后,由 ConfigurationPropertiesBindingPostProcessor 处理的,最终会委托给 Environment 来处理(参看:SpringBoot 配置项解析)。
    @Value 的属性注入是在 populateBean() 的时候处理的,是当作依赖进行注入的。最后是通过 AbstractBeanFactory.embeddedValueResolvers (一组 StringValueResoulver 的集合)  解析的,它非常强大,支持 占位符 ${} spEL(#{})

    org.springframework.beans.factory.support.AbstractBeanFactory#resolveEmbeddedValue()

    public String resolveEmbeddedValue(@Nullable String value) {
        if (value == null) {
            return null;
        }
        String result = value;
        for (StringValueResolver resolver : this.embeddedValueResolvers) {
            result = resolver.resolveStringValue(result);
            if (result == null) {
                return null;
            }
        }
        return result;
    }

    StringValueResolver、EmbeddedValueResolver
    EmbeddedValueResolver implements StringValueResolver。EmbeddedValueResolver 非常强大,它是 spring 配置解析的核心。先解析占位符 ${},再解析 spEL(#{})

     1 public class EmbeddedValueResolver implements StringValueResolver {
     2     private final BeanExpressionContext exprContext;
     3     private final BeanExpressionResolver exprResolver;
     4 
     5     public EmbeddedValueResolver(ConfigurableBeanFactory beanFactory) {
     6         this.exprContext = new BeanExpressionContext(beanFactory, null);
     7         this.exprResolver = beanFactory.getBeanExpressionResolver(); // 实现类为:StandardBeanExpressionResolver
     8     }
     9 
    10     @Override
    11     public String resolveStringValue(String strVal) {
    12         // 1. 解析占位符${}
    13         String value = this.exprContext.getBeanFactory().resolveEmbeddedValue(strVal);
    14         if (this.exprResolver != null && value != null) {
    15             // 2. 解析 spEL: #{}
    16             Object evaluated = this.exprResolver.evaluate(value, this.exprContext);
    17             value = (evaluated != null ? evaluated.toString() : null);
    18         }
    19         return value;
    20     }
    21 
    22 }

    配置写法小技巧:
    可以使用嵌套写法 和 默认值。举例:
    ${server.error.path:${error.path:/error}}

    问题思考:
    用了 disconf 之后,在使用 SpringBoot @ConfigurationProperties 形式的配置时,是不是就不用写 @PropertySource("classpath:redis.properties") 来指定配置文件了?因为 diconf 已经将托管的 property 配置文件纳入 spring 管理了,如果这样该多方便啊。那确实可以这么干吗?
    (在使用 disconf 托管配置文件时,会配置 org.springframework.context.support.PropertySourcesPlaceholderConfigurer 或者 com.baidu.disconf.client.addons.properties.ReloadingPropertyPlaceholderConfigurer,被托管的配置都会纳入 spring 管理。)

    分析:
    通过测试发现是不可以的,因为 @ConfigurationProperties 最终委托给 Environment 来处理,而 PropertySourcesPlaceholderConfigurer 和 ReloadingPropertyPlaceholderConfigurer 都不受 Environment 控制,所以是不支持的。
    而 @Value 却是可以注入 disconf 托管的配置的,因为 @Value 注入的配置会通过 StringValueResoulver 来解析,而 PropertySourcesPlaceholderConfigurer 和 ReloadingPropertyPlaceholderConfigurer 管理的配置,最终会间接通过 StringValueResolver 来解析

    资料:
    https://blog.csdn.net/f641385712/article/details/91380598

  • 相关阅读:
    编程语言的简介
    ava 8 stream的详细用法
    Java 8 Steam 例子整理
    redis常用命令
    常用正则表达式
    保留一些常用文章
    tag的简单使用
    GitFlow详解教程
    Git基本命令和GitFlow工作流
    Redis 2.8.18 安装报错 error: jemalloc/jemalloc.h: No such file or directory
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/12213644.html
Copyright © 2011-2022 走看看