美文网首页
Spring 获取配置的三种方式

Spring 获取配置的三种方式

作者: cartoony | 来源:发表于2022-03-08 00:55 被阅读0次

前言

最近在写框架时遇到需要根据特定配置(可能不存在)加载 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. 配置名不能被有效枚举到<br />2. 每一个配置的使用都需重新定义,使用较为麻烦<br />3. 项目强依赖配置的定义,配置不存在则会导致项目无法启动 1. 项目强依赖该配置的加载,想要从源头避免因配置缺失导致的未知问题<br />2. 只想使用少数几个配置
通过 @ConfigurationProperties + 前缀方式批量获取 1. 使用配置只需确定 key 的前缀即能使用,有利于批量获取场景的使用 <br />2. 因采用前缀匹配,所以在使用新的相同前缀 key 的配置时无需改动代码 1. 使用复杂,需定义配置类或者手动创建 bean 后引入使用<br />2. 增加新的前缀相同 key 时可能会引入不稳定因素 1. 需要同时使用多前缀相同 key 的配置<br />2. 期望增加新配置但不修改代码的 properties 注入
通过 Environment 动态获取单个配置 1. 获取的配置的 key 可不提前定义,程序灵活性高<br />2. 配置 key 可使用枚举统一放置与管理 1. 使用较复杂,需继承 Environment 接口形成工具类进行获取<br />2. 获取 key 对应的枚举与 key 定义分离,value 获取链路较长 1. 只需使用少量的配置<br />2. 获取配置的 key 无提前定义,需要根据对配置的有无进行灵活使用

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

相关文章

  • 6、Spring-XML配置

    一、概要 配置方式 Spring支持三种方式配置Bean,Spring1.0仅支持基于XML的配置,Spring2...

  • SpringAOP使用

    目前 Spring AOP 一共有三种配置方式。 Spring 1.2 基于接口的配置:最早的 Spring AO...

  • Spring 获取配置的三种方式

    前言 最近在写框架时遇到需要根据特定配置(可能不存在)加载 bean 的需求,所以就学习了下 Spring 中如何...

  • Spring配置方式

    Spring有三种配置方式: XML配置 注解配置(annotation) Java配置 XML配置 最经典 注解...

  • RabbitMQ如何保证消息的可靠投递?

    Spring Boot整合RabbitMQ Spring有三种配置方式 基于XML 基于JavaConfig 基于...

  • SpringBoot源码分析-004 创建容器

    第三步: 总结: Spring bean配置方式有三种:基于XML的配置方式 、基于注解的配置方式和基于Java类...

  • Spring 注解使用

    常用注解 Spring中有三种配置方式:基于XML的配置、基于注解的配置、基于Java的配置。 使用原则: 1、S...

  • Spring学习-1

    一:Spring中配置文件的加载原理: 二:常用的Spring配置文件的加载方式: 有三种分别是: 1:使用我们当...

  • spring梳理(一)bean装配方式介绍

    spring 装配bean有三种基本方式: xml配置方式 java config方式 自动装配方式 1. xml...

  • Spring的java配置方式

    Spring的java配置方式 一、Spring的java配置方式 Java配置是Spring4.x推荐的配置方式...

网友评论

      本文标题:Spring 获取配置的三种方式

      本文链接:https://www.haomeiwen.com/subject/piiorrtx.html