关于spring:Spring-获取配置的三种方式

95次阅读

共计 4469 个字符,预计需要花费 12 分钟才能阅读完成。

前言

最近在写框架时遇到须要依据特定配置(可能不存在)加载 bean 的需要,所以就学习了下 Spring 中如何获取配置的几种形式。

Spring 中获取配置的三种形式

  1. 通过 @Value 形式动静获取单个配置
  2. 通过 @ConfigurationProperties + 前缀形式批量获取配置
  3. 通过 Environment 动静获取单个配置

通过 @Value 动静获取单个配置

  1. 作用

    1. 可润饰到任一变量获取,应用较灵便
  2. 长处

    1. 应用简略,且应用关联的链路较短
  3. 毛病

    1. 配置名不能被无效枚举到
    2. 每一个配置的应用都需从新定义,应用较为麻烦
    3. 我的项目强依赖配置的定义,配置不存在则会导致我的项目无奈启动
  4. 应用场景

    1. 我的项目强依赖该配置的加载,想要从源头防止因配置缺失导致的未知问题
    2. 只想应用少数几个配置
  5. 代码示例

    @Configuration
    public class ConfigByValueAnnotation {@Value("${server.port}")
        private String serverPort;
    
        public String getServerPort() {return serverPort;}
    }
  6. 测试代码
@DisplayName("multipart get config")
@SpringBootTest
public class MultipartGetConfigTest {private static final Logger log = LoggerFactory.getLogger(MultipartGetConfigTest.class);

    @Autowired
    private ConfigByValueAnnotation configByValueAnnotation;

    @Test
    public void getByValueAnnotation(){log.info("get by @Value, value: {}", configByValueAnnotation.getServerPort());
    }
}
  1. 测试后果
org.spring.demo.MultipartGetConfigTest   : get by @Value, value: 7100

通过 @ConfigurationProperties + 前缀形式批量获取

  1. 作用

    1. 用于配置类的润饰或批量配置的获取
  2. 长处

    1. 应用配置只需确定 key 的前缀即能应用,有利于批量获取场景的应用
    2. 因采纳前缀匹配,所以在应用新的雷同前缀 key 的配置时无需改变代码
  3. 毛病

    1. 应用简单,需定义配置类或者手动创立 bean 后引入应用
    2. 减少新的前缀雷同 key 时可能会引入不稳固因素
  4. 应用场景

    1. 须要同时应用多前缀雷同 key 的配置
    2. 冀望减少新配置但不批改代码的 properties 注入
  5. 代码示例

    @Component
    @ConfigurationProperties(prefix = "server", ignoreInvalidFields = true)
    public class ConfigByConfigurationProperties {
    
        private Integer port;
    
        public Integer getPort() {return port;}
    
        public ConfigByConfigurationProperties setPort(Integer port) {
            this.port = port;
            return this;
        }
    }
    @Configuration
    public class ConfigByConfigurationPropertiesV2 {@Bean("configByValueAnnotationV2")
        @ConfigurationProperties(prefix = "server2")
        public Properties properties(){return new Properties();
        }
    
    }
    1. 测试代码
@DisplayName("multipart get config")
@SpringBootTest
public class MultipartGetConfigTest {private static final Logger log = LoggerFactory.getLogger(MultipartGetConfigTest.class);
    
       @Autowired
       private ConfigByConfigurationProperties configByConfigurationProperties;
    
       @Autowired
       @Qualifier("configByValueAnnotationV2")
       private Properties properties;
    
       @Test
       public void getByConfigurationProperties(){log.info("get by @ConfigurationProperties, value: {}", configByConfigurationProperties.getPort());
           log.info("get by @ConfigurationProperties and manual create bean, value: {}", properties.getProperty("port"));
       }

}
  1. 测试后果
org.spring.demo.MultipartGetConfigTest   : get by @ConfigurationProperties, value: 7100
org.spring.demo.MultipartGetConfigTest   : get by @ConfigurationProperties and manual create bean, value: 7100

通过 Environment 动静获取单个配置

  1. 作用

    1. 用于动静在程序代码中获取配置,而配置 key 不需提前定义
  2. 长处

    1. 获取的配置的 key 可不提前定义,程序灵活性高
    2. 配置 key 可应用枚举对立搁置与治理
  3. 毛病

    1. 应用较简单,需继承 Environment 接口造成工具类进行获取
    2. 获取 key 对应的枚举与 key 定义拆散,value 获取链路较长
  4. 应用场景

    1. 只需应用大量的配置
    2. 获取配置的 key 无提前定义,须要依据对配置的有无进行灵便应用
  5. 代码示例

    @Component
    public class ConfigByEnvironment implements EnvironmentAware {private static final Logger log = LoggerFactory.getLogger(ConfigByEnvironment.class);
     
      private Environment environment;
     
      public Optional<String> get(String configKey){String config = environment.getProperty(configKey);
          return Objects.isNull(config) ? Optional.empty() : Optional.of(config);
      }
     
      public void get(String configKey, Consumer<String> consumer){Optional<String> config = get(configKey);
          if(!config.isPresent()){log.warn("application config, get config by key fail, key: {}", configKey);
          }
          config.ifPresent(consumer);
      }
     
      @Override
      public void setEnvironment(@NonNull Environment environment) {this.environment = environment;}
    }
    
    public enum ConfigByEnvironmentKey {SERVER_PORT("server.port", "server port");
     
      private String key;
     
      private String description;
     
      ConfigByEnvironmentKey(String key, String description) {
          this.key = key;
          this.description = description;
      }
     
      public String getKey() {return key;}
     
      public String getDescription() {return description;}
    }
  1. 测试代码
@DisplayName("multipart get config")
   @SpringBootTest
   public class MultipartGetConfigTest {private static final Logger log = LoggerFactory.getLogger(MultipartGetConfigTest.class);
    
       @Autowired
       private ConfigByEnvironment configByEnvironment;
    
       @Test
       public void getByEnvironment(){configByEnvironment.get(ConfigByEnvironmentKey.SERVER_PORT.getKey()).ifPresent(value -> log.info("get by environment, value: {}", value));
       }

}
  1. 测试后果
org.spring.demo.MultipartGetConfigTest   : get by environment, value: 7100

总结

获取配置形式 长处 毛病 应用场景
通过 @Value 动静获取单个配置 应用简略,且应用关联的链路较短 1. 配置名不能被无效枚举到
2. 每一个配置的应用都需从新定义,应用较为麻烦
3. 我的项目强依赖配置的定义,配置不存在则会导致我的项目无奈启动
1. 我的项目强依赖该配置的加载,想要从源头防止因配置缺失导致的未知问题
2. 只想应用少数几个配置
通过 @ConfigurationProperties + 前缀形式批量获取 1. 应用配置只需确定 key 的前缀即能应用,有利于批量获取场景的应用
2. 因采纳前缀匹配,所以在应用新的雷同前缀 key 的配置时无需改变代码
1. 应用简单,需定义配置类或者手动创立 bean 后引入应用
2. 减少新的前缀雷同 key 时可能会引入不稳固因素
1. 须要同时应用多前缀雷同 key 的配置
2. 冀望减少新配置但不批改代码的 properties 注入
通过 Environment 动静获取单个配置 1. 获取的配置的 key 可不提前定义,程序灵活性高
2. 配置 key 可应用枚举对立搁置与治理
1. 应用较简单,需继承 Environment 接口造成工具类进行获取
2. 获取 key 对应的枚举与 key 定义拆散,value 获取链路较长
1. 只需应用大量的配置
2. 获取配置的 key 无提前定义,须要依据对配置的有无进行灵便应用

本代码示例已搁置于 github,测试代码地位,有须要的可自取。
本文首发于 cartoon 的博客

正文完
 0