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

目录
  • 前言
  • 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 获取配置的资料请关注我们其它相关文章!

(0)

相关推荐

  • SpringBoot中@ConfigurationProperties实现配置自动绑定的方法

    目录 代码 构造器绑定 结合@PropertySource 代码 pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=&

  • spring+apollo动态获取yaml格式的配置方式

    默认spring装载的都是.properties格式的配置文件,但是有时我们需要定义list或者map类型的配置,那么yaml就具有优势. 以下演示利用apollo来完成自动更新ip白名单的功能 1.重写配置工厂 public class YmlPropertySourceFactory extends DefaultPropertySourceFactory { public PropertySource<?> createPropertySource(String name, Encode

  • Spring如何利用@Value注解读取yml中的map配置

    目录 @Value注解读取yml中的map配置 下边是我在yml中的map写法 使用时候注解的写法 举个例子 spring注解@Value通过yml文件注入map yml文件 java代码注入 @Value注解读取yml中的map配置 网上查了好多资料,都是.properties文件中读取,而且又是几个人抄来抄去,找了半天功夫不负有心人,终于找到了详尽的用法介绍. 下边是我在yml中的map写法 test:   map: '{"test1":"12345",&quo

  • SpringBoot @ConfigurationProperties注解的简单使用

    源码 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ConfigurationProperties { @AliasFor("prefix") String value() default ""; @AliasFor("value") String prefix()

  • spring 自定义让@Value被解析到

    目录 spring 自定义让@Value解析到 背景 实现原理 Spring4自定义@Value功能 演示@Value的用法 我们定义一个注解 spring 自定义让@Value解析到 @Value 可以给字段赋值 背景 @Value通常与@PropertySource(value = "db.properties") 组合使用读取配置注入参数,那如果我们的值是其它存储,如何才能自动赋值 实现原理 实现很简单 //自动注入此对象 @Autowired private Environme

  • 详解Spring中的Environment外部化配置管理

    目录 profiles ProfileService 声明一个配置类 定义测试方法 profiles总结 Properties environment的应用 指定profile属性 @Value注解的使用 SpringEnvironment原理设计 Environment的中文意思是环境,它表示整个spring应用运行时的环境信息,它包含两个关键因素 profiles properties profiles profiles这个概念相信大家都已经理解了,最常见的就是不同环境下,决定当前sprin

  • SpringBoot 属性配置中获取值的方式

    目录 SpringBoot 属性配置中获取值 首先,定义一个实体类去写属性 测试和生产区分 SpringBoot 获取值和配置文件 1.@ConfigurationProperties(prefix = "student")方式 2.@Value方式 3.@PropertySource 4.@ImportResource和@Bean SpringBoot 属性配置中获取值 在配置文件中定义属性的值,然后再获取,在这里做一个总结,首先,在application.yml文件中定义端口和属性

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

    目录 前言 Spring中获取配置的三种方式 通过@Value动态获取单个配置 通过@ConfigurationProperties+前缀方式批量获取 通过Environment动态获取单个配置 总结 前言 最近在写框架时遇到需要根据特定配置(可能不存在)加载 bean 的需求,所以就学习了下 Spring 中如何获取配置的几种方式. Spring 中获取配置的三种方式 通过 @Value 方式动态获取单个配置 通过 @ConfigurationProperties + 前缀方式批量获取配置 通

  • 详解Spring依赖注入的三种方式以及优缺点

    目录 0.概述 1.属性注入 1.1 优点分析 1.2 缺点分析 2.Setter 注入 优缺点分析 3.构造方法注入 优点分析 总结 0.概述 在 Spring 中实现依赖注入的常见方式有以下 3 种: 属性注入(Field Injection): Setter 注入(Setter Injection): 构造方法注入(Constructor Injection). 它们的具体使用和优缺点分析如下. 1.属性注入 属性注入是我们最熟悉,也是日常开发中使用最多的一种注入方式,它的实现代码如下:

  • 详解Spring全局异常处理的三种方式

    在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大. 那么,能不能将所有类型的异常处理从各处理过程解耦出来,这样既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护?答案是肯定的.下面将介绍使用Spring MVC统一处理异常的解决和实现过程 使用Spring MVC提供的SimpleMappingE

  • 详解SpringBoot禁用Swagger的三种方式

    目录 摘要 方法 禁用方法1: 禁用方法2: 禁用方法3: 摘要 在生产环境下,我们需要关闭swagger配置,避免暴露接口的这种危险行为. 方法 禁用方法1: 使用注解 @Value() 推荐使用 package com.dc.config; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Be

  • 详解Springboot下载Excel的三种方式

    汇总一下浏览器下载和代码本地下载实现的3种方式. (其实一般都是在代码生成excel,然后上传到oss,然后传链接给前台,但是我好像没有实现过直接点击就能在浏览器下载的功能,所以这次一起汇总一下3种实现方式.)

  • 详解Spring集成Redis的两种方式

    目录 一.使用Jedis方式集成 1.增加依赖 2.配置项 3.配置连接池 4.测试 使用spring-data-redis 1.引入依赖 2.配置项 3.使用 4.可能会遇到的坑 哨兵和集群 总结: 在工作中,我们用到分布式缓存的时候,第一选择就是Redis,今天介绍一下SpringBoot如何集成Redis的,分别使用Jedis和Spring-data-redis两种方式. 一.使用Jedis方式集成 1.增加依赖 <!-- spring-boot-starter-web不是必须的,这里是为

  • 详解mysql数据去重的三种方式

    目录 一.背景 二.数据去重三种方法使用 1.​通过MySQL DISTINCT:去重(过滤重复数据) 2.group by 3.row_number窗口函数 三.总结 一.背景 最近在和系统模块做数据联调,其中有一个需求是将两个角色下的相关数据​对比后将最新的数据返回出去,于是就想到了去重,再次做一个总结. 二.数据去重三种方法使用 1.​通过MySQL DISTINCT:去重(过滤重复数据) ​ 1.1.在使用 mysql SELECT 语句查询数据的时候返回的是所有匹配的行. SELECT

  • 详解SpringBoot 调用外部接口的三种方式

    目录 1.简介 2.方式一:使用原始httpClient请求 3.方式二:使用RestTemplate方法 4.方式三:使用Feign进行消费 1.简介 SpringBoot不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程.在Spring-Boot项目开发中,存在着本模块的代码需要访问外面模块接口,或外部url链接的需求, 比如在apaas开发过程中需要封装接口在接口中调用apaas提供的接口(像发起流程接口submit等等)下面也是

  • 详解iOS获取通讯录的4种方式

    本文实例为大家分享了iOS获取通讯录的4种方式,供大家参考,具体内容如下 使用场景 一些App通过手机号码来推荐好友,如 微博.支付宝 首先客户端会获取通讯录中的所有手机号然后将这些手机号提交到App服务器中,服务器会查找每个手机号对应的App账号如QQ号码返回到客户端,然后客户端根据服务器返回的账号列表来推荐好友. 获取联系人方式 方案一:AddressBookUI.framework框架 提供了联系人列表界面.联系人详情界面.添加联系人界面等 一般用于选择联系人 方案二:AddressBoo

  • 详解iOS设置字体的三种方式

    有时候项目需要显示一些非系统的字体达到一些UI的效果,目前设置字体有三种方式,默认方式.bundle方式,coreText方式. 1 默认方式 这种方式就是正常的字体设置方式 label.font = [UIFont fontwithname:@"Blazed" size:42]; 至于第一个参数的名字,可以通过以下方法输出所有字体名字列表 [UIFont familyNames] 只要名字列表中存在的,都可以用这种方式关联到对应的字体上. 2 绑定自定义的字体包 其实第二种方式和第一

随机推荐