详解Spring获取配置的三种方式

 更新时间:2022年03月08日 08:30:50   作者:cartoon  
这篇文章主要为大家详细介绍了Spring获取配置的三种方式:@Value方式动态获取单个配置、@ConfigurationProperties+前缀方式批量获取配置以及Environment动态获取单个配置,感兴趣的可以了解一下

前言

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

Spring 中获取配置的三种方式

  • 通过 @Value 方式动态获取单个配置
  • 通过 @ConfigurationProperties + 前缀方式批量获取配置
  • 通过 Environment 动态获取单个配置

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

1.作用

可修饰到任一变量获取,使用较灵活

2.优点

使用简单,且使用关联的链路较短

3.缺点

  • 配置名不能被有效枚举到
  • 每一个配置的使用都需重新定义,使用较为麻烦
  • 项目强依赖配置的定义,配置不存在则会导致项目无法启动

4.使用场景

  • 项目强依赖该配置的加载,想要从源头避免因配置缺失导致的未知问题
  • 只想使用少数几个配置

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());
    }
}

7.测试结果

org.spring.demo.MultipartGetConfigTest   : get by @Value, value: 7100

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

1.作用

用于配置类的修饰或批量配置的获取

2.优点

  • 使用配置只需确定 key 的前缀即能使用,有利于批量获取场景的使用
  • 因采用前缀匹配,所以在使用新的相同前缀 key 的配置时无需改动代码

3.缺点

  • 使用复杂,需定义配置类或者手动创建 bean 后引入使用
  • 增加新的前缀相同 key 时可能会引入不稳定因素

4.使用场景

  • 需要同时使用多前缀相同 key 的配置
  • 期望增加新配置但不修改代码的 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();
    }

}

6.测试代码

@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"));
       }

}

7.测试结果

org.spring.demo.MultipartGetConfigTest   : get by @ConfigurationProperties, value: 7100
org.spring.demo.MultipartGetConfigTest   : get by @ConfigurationProperties and manual create bean, value: 7100

通过 Environment 动态获取单个配置

1.作用

用于动态在程序代码中获取配置,而配置 key 不需提前定义

2.优点

  • 获取的配置的 key 可不提前定义,程序灵活性高
  • 配置 key 可使用枚举统一放置与管理

3.缺点

  • 使用较复杂,需继承 Environment 接口形成工具类进行获取
  • 获取 key 对应的枚举与 key 定义分离,value 获取链路较长

4.使用场景

  • 只需使用少量的配置
  • 获取配置的 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;
  }
}

6.测试代码

@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));
       }

}

7.测试结果

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 无提前定义,需要根据对配置的有无进行灵活使用

以上就是详解Spring获取配置的三种方式的详细内容,更多关于Spring 获取配置的资料请关注脚本之家其它相关文章!

相关文章

  • Java中的ClassLoader类加载器使用详解

    Java中的ClassLoader类加载器使用详解

    这篇文章主要介绍了Java中的ClassLoader类加载器使用详解,ClassLoader用于将CLASS文件动态加载到JVM中去,是所有类加载器的基类,所有继承自抽象的ClassLoader的加载器,都会优先判断是否被父类加载器加载过,防止多次加载,需要的朋友可以参考下
    2023-10-10
  • springboot实现后台上传图片(工具类)

    springboot实现后台上传图片(工具类)

    这篇文章主要为大家详细介绍了springboot实现后台上传图片,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-04-04
  • java如何使用redis加锁

    java如何使用redis加锁

    这篇文章主要介绍了java如何使用redis加锁问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • Java14发布了,再也不怕NullPointerException了

    Java14发布了,再也不怕NullPointerException了

    这篇文章主要介绍了Java14发布了,再也不怕NullPointerException了,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2020-03-03
  • IDEA SpringBoot项目配置热更新的步骤详解(无需每次手动重启服务器)

    IDEA SpringBoot项目配置热更新的步骤详解(无需每次手动重启服务器)

    这篇文章主要介绍了IDEA SpringBoot项目配置热更新的步骤,无需每次手动重启服务器,本文通过图文实例代码相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • Java项目之java+springboot+ssm实现理财管理系统设计

    Java项目之java+springboot+ssm实现理财管理系统设计

    这篇文章主要介绍了Java项目java+springboot+ssm实现理财管理系统设计,使用了当前较为流行的spring boot,spring,spring mvc,mybatis,shiro框架分页处理使用了pagehelper进行操作,需要的朋友可以参考一下
    2022-03-03
  • tomcat301与java301解析

    tomcat301与java301解析

    这篇文章主要介绍了omcat301与java301,有需要的朋友可以参考一下
    2014-01-01
  • spring IOC中三种依赖注入方式

    spring IOC中三种依赖注入方式

    这篇文章主要介绍了spring IOC中三种依赖注入方式,Spring使用注入方式,为什么使用注入方式,这系列问题实际归结起来就是一句话,Spring的注入和IoC(本人关于IoC的阐述)反转控制是一回事
    2021-08-08
  • IDEA2023版本创建Spring项目只能勾选17和21却无法使用Java8的完美解决方案

    IDEA2023版本创建Spring项目只能勾选17和21却无法使用Java8的完美解决方案

    想创建一个springboot的项目,本地安装的是1.8,但是在使用Spring Initializr创建项目时,发现版本只有17和21,这篇文章主要介绍了IDEA2023版本创建Sping项目只能勾选17和21,却无法使用Java8的解决方法,需要的朋友可以参考下
    2023-12-12
  • 详解Spring整合mybatis--Spring中的事务管理(xml形式)

    详解Spring整合mybatis--Spring中的事务管理(xml形式)

    这篇文章主要介绍了Spring整合mybatis--Spring中的事务管理(xml形式),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-11-11

最新评论