写点什么

Spring Boot「08」设置和使用 Property

作者:Samson
  • 2022-10-18
    上海
  • 本文字数:2322 字

    阅读完需:约 1 分钟

Spring Boot「08」设置和使用 Property

Spring Boot 中的一个显著特性就是对外部化配置(externalized configuration)的支持。今天我们将围绕两个问题来学习下 Spring / Spring Boot 中如何使用外部配置文件的。首先,我们先来了解下如何向 Spring 框架中注册一个配置文件和如何使用配置文件中的值。然后,我们会一块学习下 Spring Boot 是如何简化和增强 Spring 框架中对外部配置文件的注册和使用的。好了,废话不多说,让我们直奔主题吧。

01-注册 Property 文件

使用@PropertySource注解,通过指定属性文件路径,Spring 框架会自动加载属性文件中的内容,并将加载到的属性添加到 Environment 中。这就是 Spring 框架提供的机制。其使用示例如下:


@Configuration@PropertySource("classpath:foo.properties")public class SomeConfig {    //...}
复制代码


注:在指定属性文件路径时,支持使用现有的属性值作为占位符,例如:


// 如果在 foo.properties 中定义了 var=foo,或者运行时传递了参数 --var=foo// 那么, ${var:default}.properties 就为 foo.properties,否则,为 default.properties@PropertySource("classpath:foo.properties")@PropertySource("classpath:properties/${var:default}.properties")
复制代码


Java 8 及以上版本支持上述写法来引入多个属性文件。如果使用 Java 7 及以下版本,可以使用@PropertyResources来同时引入多个属性文件。下述为 Java 7 及以下版本的等价写法:


@PropertySources({        @PropertySource("classpath:properties/foo.properties"),        @PropertySource("classpath:properties/${var:default}.properties")})
复制代码

02-使用 Property

两种方式:


  • @Value注解,其 value 值可以是属性占位符${...}或者 SpEL 表达式#{...}

  • 实现EnvironmentAware接口获得 Environment 对象,然后调用其 getProperty 方法,获得注册在 Environment 中的属性值。

03-Spring Boot 中对 Property 的高级特性

默认情况下,Spring Boot 启动时会自动加载如下路径中的 application.properties 和 application.yaml 属性文件:


  • optional:classpath:/;optional:classpath:/config/

  • optional:file:./;optional:file:./config/;optional:file:./config/*/


注意:optional 意味可选地、非必须的,若没有 optional,Spring Boot 在找不到文件时,会抛 ConfigDataLocationNotFoundException 异常;以";"分割的多个文件或路径同属一个 group;当值为路径时,必须以"/"或"/"结尾;""为通配符,仅用在值为路径时,且只能出现一次,且只能以"*/"结尾方式出现


加载的属性文件会被添加到 Environment 中的 PropertySources 中。


使用spring.config.location会替换掉默认的查找路径,如果想加载额外的查找路径,可以使用spring.config.additional-location。例如,如果不设置spring.config.location,而设置spring.config.additional-location=optional:classpath:/custom-config/,optional:file:./custom-config/,则 Spring Boot 的查找路径为:


  • optional:classpath:/;optional:classpath:/config/

  • optional:file:./;optional:file:./config/;optional:file:./config/*/

  • optional:classpath:/custom-config/

  • optional:file:./custom-config/


通过spring.config.name可以改变 Spring Boot 将要寻找的属性文件的名称,例如spring.config.name=myConfig,则 Spring Boot 会在上述路径中查找 myConfig.properties 和 myConfig.yaml 文件,而非 application.properties 和 application.yaml


spring.config.name/spring.config.location/spring.config.additional-location 变量必须在应用启动之前就设置(即可以在 environment / system / 命令行等中指定)envrionment


Spring Boot 中有 profile 的概念,并可通过spring.profiles.active属性值来控制激活某个或某些 profile。之后,Spring Boot 会自动在上述路径加载 application-${active_profile}.properties 文件。application.properties 文件仍会被加载,不过其中的变量值会被 application-${active_profile}.properties 中对应的值覆盖。


通常spring.config.location只会指定一个文件或一个路径,不过也可指定多个,例如--spring.config.location=classpath:application.properties,classpath:config/application.properties


注意:这里","与上文提到的 group 中";"的区别:

假设,spring.profiles.active=prod,live,而且有如下三个属性文件:

/cfg

application-live.properties

/ext

application-live.properties

application-prod.properties

比较下 spring.config.location=classpath:/cfg/;classpath:/ext/ 与 spring.config.location= classpath:/cfg/,classpath:/ext/ 的区别?

前者,加载的属性文件及顺序为:

  1. /ext/application-prod.properties

  2. /cfg/application-live.properties

  3. /ext/application-live.properties


后者,加载的属性文件及顺序为:

  1. /cfg/application-live.properties

  2. /ext/application-prod.properties

  3. /ext/application-live.properties


在单元测试时,Spring Boot 会自动在 test classpath 下查找 application.properties 和 application.yaml 属性文件。在测试类上,可以通过@TestPropertySource指定加载特定的属性文件、或指定多个属性值,或通过@TestPropertySources加载多个属性文件。


@TestPropertySource(value = "classpath:properties/foo.properties", properties = {        "external.test=abc"})// 指定多个属性文件@TestPropertySources(        @TestPropertySource("classpath:properties/foo.properties"),        @TestPropertySource("classpath:properties/bar.properties"))
复制代码


发布于: 刚刚阅读数: 4
用户头像

Samson

关注

还未添加个人签名 2019-07-22 加入

InfoQ签约作者 | 阿里云社区签约作者

评论

发布
暂无评论
Spring Boot「08」设置和使用 Property_Java_Samson_InfoQ写作社区