对于最新的稳定版本,请使用 Spring Boot 3.4.0spring-doc.cadn.net.cn

外部化配置

Spring Boot 允许您外部化配置,以便您可以在不同环境中使用相同的应用程序代码。 您可以使用各种外部配置源,包括 Java 属性文件、YAML 文件、环境变量和命令行参数。spring-doc.cadn.net.cn

属性值可以通过使用@Value注解,通过 Spring 的Environment抽象,或通过@ConfigurationProperties.spring-doc.cadn.net.cn

Spring Boot 使用非常特殊的PropertySourceorder 的 ORDER 允许合理地覆盖值。 后面的属性源可以覆盖前面的属性源中定义的值。 按以下顺序考虑源:spring-doc.cadn.net.cn

  1. 默认属性(通过设置SpringApplication.setDefaultProperties(Map)).spring-doc.cadn.net.cn

  2. @PropertySourceannotations@Configuration类。 请注意,此类属性源不会添加到Environment直到刷新应用程序上下文。 现在配置某些属性(例如logging.*spring.main.*,这些 API 将在刷新开始之前读取。spring-doc.cadn.net.cn

  3. 配置数据(例如application.properties文件)。spring-doc.cadn.net.cn

  4. 一个RandomValuePropertySource仅在random.*.spring-doc.cadn.net.cn

  5. OS 环境变量。spring-doc.cadn.net.cn

  6. Java 系统属性 (System.getProperties()).spring-doc.cadn.net.cn

  7. JNDI 属性来自java:comp/env.spring-doc.cadn.net.cn

  8. ServletContextinit 参数。spring-doc.cadn.net.cn

  9. ServletConfiginit 参数。spring-doc.cadn.net.cn

  10. 属性来自SPRING_APPLICATION_JSON(嵌入在环境变量或系统属性中的内联 JSON)。spring-doc.cadn.net.cn

  11. 命令行参数。spring-doc.cadn.net.cn

  12. properties属性。 适用于@SpringBootTest以及用于测试应用程序的特定切片的 test annotationsspring-doc.cadn.net.cn

  13. @DynamicPropertySource注解。spring-doc.cadn.net.cn

  14. @TestPropertySourceComments 的 Comments。spring-doc.cadn.net.cn

  15. Devtools 全局设置属性$HOME/.config/spring-boot目录(当 DevTools 处于活动状态时)。spring-doc.cadn.net.cn

配置数据文件按以下顺序考虑:spring-doc.cadn.net.cn

  1. 打包在 jar 中的 Application 属性application.properties和 YAML 变体)。spring-doc.cadn.net.cn

  2. 打包在 jar 中的 Profile 特定应用程序属性application-{profile}.properties和 YAML 变体)。spring-doc.cadn.net.cn

  3. 打包的 jar 之外的应用程序属性application.properties和 YAML 变体)。spring-doc.cadn.net.cn

  4. 打包的 jar 之外特定于配置文件的应用程序属性application-{profile}.properties和 YAML 变体)。spring-doc.cadn.net.cn

建议整个应用程序坚持使用一种格式。 如果您的配置文件同时包含.properties和 YAML 格式,则.properties优先。
如果使用环境变量而不是系统属性,则大多数作系统不允许使用句点分隔的键名称,但您可以使用下划线代替(例如SPRING_CONFIG_NAME而不是spring.config.name). 有关详细信息,请参阅从环境变量绑定
如果您的应用程序在 servlet 容器或应用程序服务器中运行,则 JNDI 属性(在java:comp/env) 或 Servlet 上下文初始化参数来代替环境变量或系统属性。

为了提供一个具体的例子,假设您开发了一个@Component它使用name属性,如以下示例所示:spring-doc.cadn.net.cn

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

	@Value("${name}")
	private String name;

	// ...

}

在应用程序类路径上(例如,在 jar 中),您可以有一个application.properties文件,该文件为name. 在新环境中运行时,application.properties文件可以在 jar 外部提供,该文件会覆盖name. 对于一次性测试,您可以使用特定的命令行开关(例如java -jar app.jar --name="Spring").spring-doc.cadn.net.cn

envconfigpropsendpoints 可用于确定属性具有特定值的原因。 您可以使用这两个终端节点来诊断意外的属性值。 有关详细信息,请参阅 生产就绪功能 部分。

访问命令行属性

默认情况下,SpringApplication转换任何命令行选项参数(即以 开头的参数,例如----server.port=9000) 转换为property并将它们添加到 Spring 中Environment. 如前所述,命令行属性始终优先于基于文件的属性源。spring-doc.cadn.net.cn

如果您不希望将命令行属性添加到Environment中,您可以使用SpringApplication.setAddCommandLineProperties(false).spring-doc.cadn.net.cn

JSON 应用程序属性

环境变量和系统属性通常具有限制,这意味着无法使用某些属性名称。 为了帮助解决这个问题, Spring Boot 允许您将一个属性块编码为单个 JSON 结构。spring-doc.cadn.net.cn

当您的应用程序启动时,任何spring.application.jsonSPRING_APPLICATION_JSONproperties 将被解析并添加到Environment.spring-doc.cadn.net.cn

例如,SPRING_APPLICATION_JSONproperty 可以作为环境变量在 UN*X shell 的命令行中提供:spring-doc.cadn.net.cn

$ SPRING_APPLICATION_JSON='{"my":{"name":"test"}}' java -jar myapp.jar

在前面的示例中,您最终会得到my.name=test在SpringEnvironment.spring-doc.cadn.net.cn

相同的 JSON 也可以作为系统属性提供:spring-doc.cadn.net.cn

$ java -Dspring.application.json='{"my":{"name":"test"}}' -jar myapp.jar

或者,您可以使用命令行参数提供 JSON:spring-doc.cadn.net.cn

$ java -jar myapp.jar --spring.application.json='{"my":{"name":"test"}}'

如果要部署到经典 Application Server,还可以使用名为java:comp/env/spring.application.json.spring-doc.cadn.net.cn

虽然nullJSON 中的值将添加到生成的属性源中,PropertySourcesPropertyResolver对待nullproperties 作为缺失值。 这意味着 JSON 无法使用null价值。

外部应用程序属性

Spring Boot 将自动查找并加载application.propertiesapplication.yaml应用程序启动时从以下位置获取的文件:spring-doc.cadn.net.cn

  1. 从 classpathspring-doc.cadn.net.cn

    1. 类路径根spring-doc.cadn.net.cn

    2. 类路径/configspring-doc.cadn.net.cn

  2. 从当前目录spring-doc.cadn.net.cn

    1. 当前目录spring-doc.cadn.net.cn

    2. config/子目录spring-doc.cadn.net.cn

    3. 的直接子目录config/子目录spring-doc.cadn.net.cn

该列表按优先级排序(较低项中的值将覆盖较早项的值)。 加载文件中的文档将添加为PropertySource实例添加到 SpringEnvironment.spring-doc.cadn.net.cn

如果您不喜欢application作为配置文件名称,您可以通过指定spring.config.nameenvironment 属性。 例如,要查找myproject.propertiesmyproject.yaml文件,您可以按如下方式运行应用程序:spring-doc.cadn.net.cn

$ java -jar myproject.jar --spring.config.name=myproject

您还可以使用spring.config.locationenvironment 属性。 此属性接受要检查的一个或多个位置的逗号分隔列表。spring-doc.cadn.net.cn

以下示例显示如何指定两个不同的文件:spring-doc.cadn.net.cn

$ java -jar myproject.jar --spring.config.location=\
	optional:classpath:/default.properties,\
	optional:classpath:/override.properties
使用前缀optional:如果位置是可选的,并且您不介意它们不存在。
spring.config.name,spring.config.locationspring.config.additional-location很早就用于确定必须加载哪些文件。 它们必须定义为环境属性(通常是 OS 环境变量、系统属性或命令行参数)。

如果spring.config.location包含目录(而不是文件),它们应以 . 在运行时,它们将附加从/spring.config.name在加载之前。 在spring.config.location直接导入。spring-doc.cadn.net.cn

目录和文件位置值也都进行了扩展,以检查特定于配置文件的文件。 例如,如果你有一个spring.config.locationclasspath:myconfig.properties,您也会找到合适的classpath:myconfig-<profile>.properties文件。

在大多数情况下,每个spring.config.location项将引用单个文件或目录。 位置按其定义顺序进行处理,较晚的位置可以覆盖较早的位置的值。spring-doc.cadn.net.cn

如果你有一个复杂的位置设置,并且你使用特定于配置文件的配置文件,你可能需要提供进一步的提示,以便 Spring Boot 知道应该如何对它们进行分组。 位置组是所有位置都被视为同一级别的位置的集合。 例如,您可能希望对所有 Classpath 位置进行分组,然后对所有外部位置进行分组。 位置组中的项目应以 分隔。 有关更多详细信息,请参阅 Profile Specific Files 部分中的示例。;spring-doc.cadn.net.cn

使用 配置 Locationspring.config.location替换 Default Locations。 例如,如果spring.config.location配置了值optional:classpath:/custom-config/,optional:file:./custom-config/,则考虑的完整位置集为:spring-doc.cadn.net.cn

  1. optional:classpath:custom-config/spring-doc.cadn.net.cn

  2. optional:file:./custom-config/spring-doc.cadn.net.cn

如果您希望添加其他位置,而不是替换它们,则可以使用spring.config.additional-location. 从其他位置加载的属性可以覆盖默认位置中的属性。 例如,如果spring.config.additional-location配置了值optional:classpath:/custom-config/,optional:file:./custom-config/,则考虑的完整位置集为:spring-doc.cadn.net.cn

  1. optional:classpath:/;optional:classpath:/config/spring-doc.cadn.net.cn

  2. optional:file:./;optional:file:./config/;optional:file:./config/*/spring-doc.cadn.net.cn

  3. optional:classpath:custom-config/spring-doc.cadn.net.cn

  4. optional:file:./custom-config/spring-doc.cadn.net.cn

此搜索顺序允许您在一个配置文件中指定默认值,然后在另一个配置文件中选择性地覆盖这些值。 您可以在application.properties(或您选择的任何其他 basenamespring.config.name) 中的一个默认位置。 然后,可以在运行时使用位于其中一个自定义位置的不同文件覆盖这些默认值。spring-doc.cadn.net.cn

可选位置

默认情况下,当指定的配置数据位置不存在时, Spring Boot 将抛出一个ConfigDataLocationNotFoundException,并且您的应用程序将无法启动。spring-doc.cadn.net.cn

如果要指定一个位置,但又不介意它并不总是存在,则可以使用optional:前缀。 您可以将此前缀与spring.config.locationspring.config.additional-location属性,以及spring.config.import声明。spring-doc.cadn.net.cn

例如,spring.config.import的值optional:file:./myconfig.properties允许您的应用程序启动,即使myconfig.properties文件丢失。spring-doc.cadn.net.cn

如果要忽略所有ConfigDataLocationNotFoundException错误并始终继续启动应用程序,您可以使用spring.config.on-not-found财产。 将值设置为ignoreSpringApplication.setDefaultProperties(…​)或使用 system/environment 变量。spring-doc.cadn.net.cn

通配符位置

如果配置文件位置包含最后一个路径段的字符,则将其视为通配符位置。 加载配置时,通配符会展开,以便同时检查直接子目录。 通配符位置在 Kubernetes 等环境中,当有多个 config 属性来源时特别有用。*spring-doc.cadn.net.cn

例如,如果您有一些 Redis 配置和一些 MySQL 配置,您可能希望将这两个配置分开,同时要求这两个配置都存在于application.properties文件。 这可能会导致两个单独的application.properties文件挂载在不同位置,例如/config/redis/application.properties/config/mysql/application.properties. 在这种情况下,将通配符位置设置为config/*/)将导致两个文件都被处理。spring-doc.cadn.net.cn

默认情况下,Spring Boot 包括config/*/在默认搜索位置。 这意味着/config目录中。spring-doc.cadn.net.cn

您可以自己将通配符位置与spring.config.locationspring.config.additional-location性能。spring-doc.cadn.net.cn

通配符位置必须仅包含一个通配符位置,并且对于目录或**/*/<filename>对于作为文件的搜索位置。 带有通配符的位置根据文件名的绝对路径按字母顺序排序。
通配符位置仅适用于外部目录。 您不能在classpath:位置。

配置文件特定

以及applicationproperty 文件,Spring Boot 还将尝试使用命名约定加载特定于配置文件的文件application-{profile}. 例如,如果您的应用程序激活了名为prod并使用 YAML 文件,那么两者application.yamlapplication-prod.yaml将被考虑。spring-doc.cadn.net.cn

特定于配置文件的属性从与标准相同的位置加载application.properties,特定于配置文件的文件始终覆盖非特定文件。 如果指定了多个配置文件,则适用 last-wins 策略。 例如,如果配置文件prod,livespring.profiles.active属性, 值application-prod.properties可以被application-live.properties.spring-doc.cadn.net.cn

“最后获胜”策略适用于营业地点组级别。 一个spring.config.locationclasspath:/cfg/,classpath:/ext/将具有与classpath:/cfg/;classpath:/ext/.spring-doc.cadn.net.cn

例如,继续我们的prod,live例如,我们可能有以下文件:spring-doc.cadn.net.cn

/cfg
  application-live.properties
/ext
  application-live.properties
  application-prod.properties

当我们有一个spring.config.locationclasspath:/cfg/,classpath:/ext/我们处理所有/cfgfiles before all (所有/ext文件:spring-doc.cadn.net.cn

  1. /cfg/application-live.propertiesspring-doc.cadn.net.cn

  2. /ext/application-prod.propertiesspring-doc.cadn.net.cn

  3. /ext/application-live.propertiesspring-doc.cadn.net.cn

当我们有classpath:/cfg/;classpath:/ext/相反(使用分隔符),我们处理;/cfg/ext在同一级别:spring-doc.cadn.net.cn

  1. /ext/application-prod.propertiesspring-doc.cadn.net.cn

  2. /cfg/application-live.propertiesspring-doc.cadn.net.cn

  3. /ext/application-live.propertiesspring-doc.cadn.net.cn

Environment具有一组默认配置文件(默认情况下,[default]),如果未设置活动配置文件,则使用该配置文件。 换句话说,如果未显式激活任何配置文件,则application-default被考虑。spring-doc.cadn.net.cn

属性文件只加载一次。 如果您已经直接导入了特定于配置文件的属性文件,则不会再次导入它。

导入其他数据

应用程序属性可以使用spring.config.import财产。 导入在被发现时进行处理,并被视为插入到声明导入的导入文档的正下方的附加文档。spring-doc.cadn.net.cn

例如,您的类路径中可能有以下内容application.properties文件:spring-doc.cadn.net.cn

spring.application.name=myapp
spring.config.import=optional:file:./dev.properties

这将触发dev.properties当前目录中的文件(如果存在此类文件)。 导入的dev.properties将优先于触发导入的文件。 在上面的示例中,dev.properties可以重新定义spring.application.name更改为不同的值。spring-doc.cadn.net.cn

无论声明多少次,导入都只会导入一次。 在 properties/yaml 文件中的单个文档中定义导入的顺序无关紧要。 例如,下面的两个示例产生相同的结果:spring-doc.cadn.net.cn

spring.config.import=my.properties
my.property=value
my.property=value
spring.config.import=my.properties

在上述两个示例中,my.propertiesfile 将优先于触发其导入的文件。spring-doc.cadn.net.cn

可以在单个spring.config.import钥匙。 位置将按照定义的顺序进行处理,以后的导入优先。spring-doc.cadn.net.cn

在适当时,还会考虑导入特定于 Profile 的变体。 上面的示例将导入my.properties以及任何my-<profile>.properties变种。

Spring Boot 包含可插拔 API,允许支持各种不同的位置地址。 默认情况下,您可以导入 Java 属性、YAML 和配置树spring-doc.cadn.net.cn

第三方 jar 可以提供对其他技术的支持(不要求文件是本地的)。 例如,您可以想象配置数据来自 Consul、Apache ZooKeeper 或 Netflix Archaius 等外部存储。spring-doc.cadn.net.cn

如果要支持自己的位置,请参阅ConfigDataLocationResolverConfigDataLoader类中的org.springframework.boot.context.config包。spring-doc.cadn.net.cn

导入无扩展名文件

某些云平台无法向卷挂载的文件添加文件扩展名。 要导入这些无扩展名文件,你需要给 Spring Boot 一个提示,以便它知道如何加载它们。 您可以通过在方括号中放置扩展提示来执行此作。spring-doc.cadn.net.cn

例如,假设您有一个/etc/config/myconfig要作为 YAML 导入的文件。 您可以从application.properties使用以下内容:spring-doc.cadn.net.cn

spring.config.import=file:/etc/config/myconfig[.yaml]

使用配置树

在云平台(如 Kubernetes)上运行应用程序时,您通常需要读取平台提供的配置值。 将环境变量用于此类目的并不少见,但这可能有缺点,尤其是在值应该保密的情况下。spring-doc.cadn.net.cn

作为环境变量的替代方案,许多云平台现在允许您将配置映射到挂载的数据卷。 例如,Kubernetes 可以同时对ConfigMapsSecrets.spring-doc.cadn.net.cn

可以使用两种常见的卷挂载模式:spring-doc.cadn.net.cn

  1. 单个文件包含一组完整的属性(通常写为 YAML)。spring-doc.cadn.net.cn

  2. 多个文件被写入目录树,文件名成为 'key',内容成为 'value'。spring-doc.cadn.net.cn

对于第一种情况,您可以直接使用spring.config.import如上所述。 对于第二种情况,您需要使用configtree:前缀,以便 Spring Boot 知道它需要将所有文件公开为属性。spring-doc.cadn.net.cn

例如,假设 Kubernetes 挂载了以下卷:spring-doc.cadn.net.cn

etc/
  config/
    myapp/
      username
      password

usernamefile 将是一个 config 值,而password将是一个秘密。spring-doc.cadn.net.cn

要导入这些属性,您可以将以下内容添加到application.propertiesapplication.yaml文件:spring-doc.cadn.net.cn

spring.config.import=optional:configtree:/etc/config/

然后,您可以访问或注入myapp.usernamemyapp.password属性Environment以通常的方式。spring-doc.cadn.net.cn

配置树下的文件夹和文件的名称构成属性名称。 在上面的示例中,要将属性作为usernamepassword中,您可以设置spring.config.importoptional:configtree:/etc/config/myapp.
带有点表示法的文件名也会正确映射。 例如,在上面的示例中,名为myapp.username/etc/config将导致myapp.username属性在Environment.
配置树值可以绑定到两个字符串Stringbyte[]类型。

如果要从同一个父文件夹导入多个配置树,则可以使用通配符快捷方式。 任何configtree:location 结尾的 Location 会将所有直接子项作为配置树导入。 与非通配符导入一样,每个配置树下的文件夹和文件的名称构成属性名称。/*/spring-doc.cadn.net.cn

例如,给定以下卷:spring-doc.cadn.net.cn

etc/
  config/
    dbconfig/
      db/
        username
        password
    mqconfig/
      mq/
        username
        password

您可以使用configtree:/etc/config/*/作为导入位置:spring-doc.cadn.net.cn

spring.config.import=optional:configtree:/etc/config/*/

这将添加db.username,db.password,mq.usernamemq.password性能。spring-doc.cadn.net.cn

使用通配符加载的目录按字母顺序排序。 如果您需要不同的顺序,则应将每个位置列为单独的导入

配置树还可用于 Docker 密钥。 当 Docker Swarm 服务被授予对 secret 的访问权限时,secret 将被挂载到容器中。 例如,如果名为db.password安装在/run/secrets/,您可以使db.password可用于 Spring 环境:spring-doc.cadn.net.cn

spring.config.import=optional:configtree:/run/secrets/

属性占位符

中的 valueapplication.propertiesapplication.yaml通过现有的Environment,以便您可以参考以前定义的值(例如,从 System properties 或 environment variables)。 标准${name}property-placeholder 语法可以在值中的任何位置使用。 属性占位符还可以使用:将默认值与属性名称分开,例如${name:default}.spring-doc.cadn.net.cn

以下示例显示了带和不带默认值的占位符的用法:spring-doc.cadn.net.cn

app.name=MyApp
app.description=${app.name} is a Spring Boot application written by ${username:Unknown}

假设usernameproperty 没有在其他位置设置,app.description将具有值MyApp is a Spring Boot application written by Unknown.spring-doc.cadn.net.cn

您应该始终使用其规范形式(kebab-case 仅使用小写字母)在占位符中引用属性名称。 这将允许 Spring Boot 使用与松散绑定时相同的逻辑 @ConfigurationProperties.spring-doc.cadn.net.cn

例如${demo.item-price}会接球demo.item-pricedemo.itemPrice表单中application.properties文件以及DEMO_ITEMPRICE从系统环境。 如果您使用了${demo.itemPrice}相反demo.item-priceDEMO_ITEMPRICE不会被考虑。spring-doc.cadn.net.cn

您还可以使用此技术创建现有 Spring Boot 属性的“短”变体。 有关详细信息,请参阅 “How-to Guides” 中的 Use 'short' Command Line Arguments 部分。

使用多文档文件

Spring Boot 允许您将单个物理文件拆分为多个逻辑文档,每个逻辑文档都是独立添加的。 文档按从上到下的顺序处理。 后面的文档可以覆盖前面文档中定义的属性。spring-doc.cadn.net.cn

application.yaml文件,则使用标准的 YAML 多文档语法。 三个连续的连字符表示一个文档的结尾和下一个文档的开头。spring-doc.cadn.net.cn

例如,以下文件有两个逻辑文档:spring-doc.cadn.net.cn

spring:
  application:
    name: "MyApp"
---
spring:
  application:
    name: "MyCloudApp"
  config:
    activate:
      on-cloud-platform: "kubernetes"

application.properties文件,一个特殊的或#---!---comment 用于标记文档拆分:spring-doc.cadn.net.cn

spring.application.name=MyApp
#---
spring.application.name=MyCloudApp
spring.config.activate.on-cloud-platform=kubernetes
属性文件分隔符不得有任何前导空格,并且必须恰好包含三个连字符。 紧接在分隔符之前和之后的行不能是相同的注释前缀。
多文档属性文件通常与激活属性结合使用,例如spring.config.activate.on-profile. 有关详细信息,请参阅下一节
无法使用@PropertySource@TestPropertySource附注。

激活属性

有时,仅在满足某些条件时激活一组给定的属性很有用。 例如,您可能具有仅在特定配置文件处于活动状态时才相关的属性。spring-doc.cadn.net.cn

您可以使用spring.config.activate.*.spring-doc.cadn.net.cn

可以使用以下激活属性:spring-doc.cadn.net.cn

表 1.激活属性
财产 注意

on-profilespring-doc.cadn.net.cn

必须匹配的配置文件表达式,文档才能处于活动状态。spring-doc.cadn.net.cn

on-cloud-platformspring-doc.cadn.net.cn

CloudPlatform必须检测到该 ID 才能使文档处于活动状态。spring-doc.cadn.net.cn

例如,以下指定第二个文档仅在 Kubernetes 上运行时处于活动状态,并且仅当 “prod” 或 “staging” 配置文件处于活动状态时:spring-doc.cadn.net.cn

myprop=always-set
#---
spring.config.activate.on-cloud-platform=kubernetes
spring.config.activate.on-profile=prod | staging
myotherprop=sometimes-set

加密属性

Spring Boot 不提供对加密属性值的任何内置支持,但是,它确实提供了修改 Spring 中包含的值所需的钩子点Environment. 这EnvironmentPostProcessor界面允许您作Environment在应用程序启动之前。 有关详细信息,请参见Customize the Environment 或 ApplicationContext Before It Startedspring-doc.cadn.net.cn

如果你需要一种安全的方式来存储凭证和密码,Spring Cloud Vault 项目提供了在 HashiCorp Vault 中存储外部化配置的支持。spring-doc.cadn.net.cn

使用 YAML

YAML 是 JSON 的超集,因此是指定分层配置数据的便捷格式。 这SpringApplication每当 Classpath 上有 SnakeYAML 库时,class 都会自动支持 YAML 作为属性的替代方案。spring-doc.cadn.net.cn

如果您使用Starters,则 SnakeYAML 由spring-boot-starter.

将 YAML 映射到属性

YAML 文档需要从它们的分层格式转换为可以与 Spring 一起使用的平面结构Environment. 例如,请考虑以下 YAML 文档:spring-doc.cadn.net.cn

environments:
  dev:
    url: "https://dev.example.com"
    name: "Developer Setup"
  prod:
    url: "https://another.example.com"
    name: "My Cool App"

为了从Environment,它们将被平展,如下所示:spring-doc.cadn.net.cn

environments.dev.url=https://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=https://another.example.com
environments.prod.name=My Cool App

同样,YAML 列表也需要扁平化。 它们表示为属性键,其中[index]dereferencers 的 dereferencers。 例如,请考虑以下 YAML:spring-doc.cadn.net.cn

 my:
  servers:
  - "dev.example.com"
  - "another.example.com"

前面的示例将转换为以下属性:spring-doc.cadn.net.cn

my.servers[0]=dev.example.com
my.servers[1]=another.example.com
使用[index]表示法可以绑定到 JavaListSet对象使用 Spring Boot 的Binder类。 有关更多详细信息,请参阅下面的类型安全配置属性部分。
无法使用@PropertySource@TestPropertySource附注。 因此,如果需要以这种方式加载值,则需要使用属性文件。

直接加载 YAML

Spring Framework 提供了两个方便的类,可用于加载 YAML 文档。 这YamlPropertiesFactoryBean将 YAML 加载为PropertiesYamlMapFactoryBean将 YAML 加载为Map.spring-doc.cadn.net.cn

您还可以使用YamlPropertySourceLoaderclass (如果要将 YAML 加载为 Spring)PropertySource.spring-doc.cadn.net.cn

配置随机值

RandomValuePropertySource对于注入随机值(例如,注入 secret 或测试用例)非常有用。 它可以生成整数、长整型、uuid 或字符串,如以下示例所示:spring-doc.cadn.net.cn

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number-less-than-ten=${random.int(10)}
my.number-in-range=${random.int[1024,65536]}

random.int*syntax 为OPEN value (,max) CLOSE其中,OPEN,CLOSE是任何字符,并且value,max是整数。 如果max,则value是最小值,而max是最大值 (不包括)。spring-doc.cadn.net.cn

配置系统环境属性

Spring Boot 支持为环境属性设置前缀。 如果系统环境由具有不同配置要求的多个 Spring Boot 应用程序共享,这将非常有用。 系统环境属性的前缀可以直接在SpringApplication.spring-doc.cadn.net.cn

例如,如果将前缀设置为input,则remote.timeout也将解析为input.remote.timeout在系统环境中。spring-doc.cadn.net.cn

类型安全的配置属性

使用@Value("${property}")Annotation 来注入配置属性有时会很麻烦,特别是当你正在使用多个属性或者你的数据本质上是分层的。 Spring Boot 提供了一种使用属性的替代方法,该方法允许强类型 bean 管理和验证应用程序的配置。spring-doc.cadn.net.cn

另请参阅 @Value和类型安全的配置属性。

JavaBean 属性绑定

可以绑定声明标准 JavaBean 属性的 Bean,如下例所示:spring-doc.cadn.net.cn

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("my.service")
public class MyProperties {

	private boolean enabled;

	private InetAddress remoteAddress;

	private final Security security = new Security();

	// getters / setters...

	public boolean isEnabled() {
		return this.enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public InetAddress getRemoteAddress() {
		return this.remoteAddress;
	}

	public void setRemoteAddress(InetAddress remoteAddress) {
		this.remoteAddress = remoteAddress;
	}

	public Security getSecurity() {
		return this.security;
	}

	public static class Security {

		private String username;

		private String password;

		private List<String> roles = new ArrayList<>(Collections.singleton("USER"));

		// getters / setters...

		public String getUsername() {
			return this.username;
		}

		public void setUsername(String username) {
			this.username = username;
		}

		public String getPassword() {
			return this.password;
		}

		public void setPassword(String password) {
			this.password = password;
		}

		public List<String> getRoles() {
			return this.roles;
		}

		public void setRoles(List<String> roles) {
			this.roles = roles;
		}

	}

}

前面的 POJO 定义了以下属性:spring-doc.cadn.net.cn

映射到@ConfigurationPropertiesSpring Boot 中可用的类(通过属性文件、YAML 文件、环境变量和其他机制进行配置)是公共 API,但类本身的访问器(getter/setter)不能直接使用。

这种安排依赖于默认的空构造函数,并且 getter 和 setter 通常是强制性的,因为绑定是通过标准 Java Beans 属性描述符进行的,就像在 Spring MVC 中一样。 在以下情况下,可以省略 setter:spring-doc.cadn.net.cn

  • 只要 Map 被初始化,就需要一个 getter,但不一定是一个 setter,因为它们可以被 binders 改变。spring-doc.cadn.net.cn

  • 可以通过索引(通常使用 YAML)或使用单个逗号分隔值(properties)来访问集合和数组。 在后一种情况下,setter 是必需的。 我们建议始终为此类类型添加 setter。 如果初始化集合,请确保它不是不可变的(如前面的示例所示)。spring-doc.cadn.net.cn

  • 如果嵌套的 POJO 属性被初始化(如Security字段),则不需要 setter。 如果希望 Binders 使用其默认构造函数动态创建实例,则需要 setter。spring-doc.cadn.net.cn

有些人使用 Project Lombok 自动添加 getter 和 setter。 确保 Lombok 不会为此类类型生成任何特定的构造函数,因为容器会自动使用它来实例化对象。spring-doc.cadn.net.cn

最后,仅考虑标准 Java Bean 属性,并且不支持对静态属性进行绑定。spring-doc.cadn.net.cn

构造函数绑定

上一节中的示例可以以不可变的方式重写,如以下示例所示:spring-doc.cadn.net.cn

import java.net.InetAddress;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.DefaultValue;

@ConfigurationProperties("my.service")
public class MyProperties {

	// fields...

	private final boolean enabled;

	private final InetAddress remoteAddress;

	private final Security security;


	public MyProperties(boolean enabled, InetAddress remoteAddress, Security security) {
		this.enabled = enabled;
		this.remoteAddress = remoteAddress;
		this.security = security;
	}

	// getters...

	public boolean isEnabled() {
		return this.enabled;
	}

	public InetAddress getRemoteAddress() {
		return this.remoteAddress;
	}

	public Security getSecurity() {
		return this.security;
	}

	public static class Security {

		// fields...

		private final String username;

		private final String password;

		private final List<String> roles;


		public Security(String username, String password, @DefaultValue("USER") List<String> roles) {
			this.username = username;
			this.password = password;
			this.roles = roles;
		}

		// getters...

		public String getUsername() {
			return this.username;
		}

		public String getPassword() {
			return this.password;
		}

		public List<String> getRoles() {
			return this.roles;
		}

	}

}

在此设置中,存在单个参数化构造函数意味着应使用构造函数绑定。 这意味着 Binder 将找到一个构造函数,其中包含您希望绑定的参数。 如果您的类有多个构造函数,则@ConstructorBindingannotation 可用于指定要用于构造函数绑定的构造函数。 要选择退出具有单个参数化构造函数的类的构造函数绑定,必须为构造函数添加@Autowired或制造private. 构造函数绑定可以与记录一起使用。 除非您的记录具有多个构造函数,否则无需使用@ConstructorBinding.spring-doc.cadn.net.cn

构造函数绑定类的嵌套成员(例如Security在上面的示例中)也将通过其构造函数进行绑定。spring-doc.cadn.net.cn

默认值可以使用@DefaultValueon constructor parameters 和 record components. 转换服务将用于强制注释的Stringvalue 设置为缺失属性的目标类型。spring-doc.cadn.net.cn

参考前面的示例,如果没有属性绑定到SecurityMyProperties实例将包含一个null的值security. 要使其包含Security即使没有绑定到任何属性(使用 Kotlin 时,这也需要usernamepassword参数Security要声明为可为 null,因为它们没有默认值),请使用空的@DefaultValue注解:spring-doc.cadn.net.cn

	public MyProperties(boolean enabled, InetAddress remoteAddress, @DefaultValue Security security) {
		this.enabled = enabled;
		this.remoteAddress = remoteAddress;
		this.security = security;
	}
要使用构造函数绑定,必须使用@EnableConfigurationProperties或配置属性 scanning。 你不能将构造函数绑定与由常规 Spring 机制创建的 bean 一起使用(例如@Componentbean, 使用 创建的 bean@Bean方法或 bean@Import)
要使用构造函数绑定,必须使用-parameters. 如果您使用 Spring Boot 的 Gradle 插件,或者如果您使用 Maven 和spring-boot-starter-parent.
的使用Optional@ConfigurationProperties不建议使用,因为它主要用作返回类型。 因此,它不太适合 configuration property injection。 为了与其他类型的属性保持一致,如果您确实声明了Optionalproperty 并且它没有值,null而不是空的Optional将被绑定。
要在属性名称中使用 reserved 关键字,例如my.service.import,请使用@Nameannotation 的 Constructor 参数。

启用 @ConfigurationProperties 注释类型

Spring Boot 提供了用于绑定的基础设施@ConfigurationProperties类型并将它们注册为 Bean。 您可以逐个类启用配置属性,也可以启用配置属性扫描,其工作方式与组件扫描类似。spring-doc.cadn.net.cn

有时,用@ConfigurationProperties可能不适合扫描,例如,如果您正在开发自己的自动配置或想要有条件地启用它们。 在这些情况下,请使用@EnableConfigurationProperties注解。 这可以在任何@Configuration类,如以下示例所示:spring-doc.cadn.net.cn

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(SomeProperties.class)
public class MyConfiguration {

}
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("some.properties")
public class SomeProperties {

}

要使用配置属性扫描,请添加@ConfigurationPropertiesScan注解添加到您的应用程序。 通常,它被添加到带有@SpringBootApplication但它可以添加到任何@Configuration类。 默认情况下,将从声明 Comments 的类的包中进行扫描。 如果要定义要扫描的特定包,可以按以下示例所示执行此作:spring-doc.cadn.net.cn

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;

@SpringBootApplication
@ConfigurationPropertiesScan({ "com.example.app", "com.example.another" })
public class MyApplication {

}

@ConfigurationProperties使用 Configuration Property scanning 或通过@EnableConfigurationProperties,该 bean 有一个约定俗成的名称:<prefix>-<fqn>哪里<prefix>是在@ConfigurationPropertiesannotation 和<fqn>是 Bean 的完全限定名称。 如果 Comments 未提供任何前缀,则仅使用 Bean 的完全限定名称。spring-doc.cadn.net.cn

假设它在com.example.apppackage 中,则SomeProperties上面的示例是some.properties-com.example.app.SomeProperties.spring-doc.cadn.net.cn

我们建议@ConfigurationProperties仅处理环境,特别是,不从上下文中注入其他 bean。 对于极端情况,可以使用 setter 注入或任何*Aware框架提供的接口(例如EnvironmentAware如果您需要访问Environment). 如果您仍然希望使用构造函数注入其他 bean,则必须使用@Component并使用基于 JavaBean 的属性绑定。spring-doc.cadn.net.cn

使用 @ConfigurationProperties 注释的类型

这种配置样式特别适用于SpringApplicationexternal YAML 配置,如以下示例所示:spring-doc.cadn.net.cn

my:
  service:
    remote-address: 192.168.1.1
    security:
      username: "admin"
      roles:
      - "USER"
      - "ADMIN"

使用@ConfigurationPropertiesbeans 中,你可以像注入任何其他 bean 一样注入它们,如以下示例所示:spring-doc.cadn.net.cn

import org.springframework.stereotype.Service;

@Service
public class MyService {

	private final MyProperties properties;

	public MyService(MyProperties properties) {
		this.properties = properties;
	}

	public void openConnection() {
		Server server = new Server(this.properties.getRemoteAddress());
		server.start();
		// ...
	}

	// ...

}
@ConfigurationProperties还允许您生成元数据文件,IDE 可以使用这些文件为您自己的键提供自动完成功能。 有关详细信息,请参阅附录

第三方配置

除了使用@ConfigurationProperties要对类进行注释,您还可以在 public 上使用它@Bean方法。 当您希望将属性绑定到不受控制的第三方组件时,这样做可能特别有用。spring-doc.cadn.net.cn

要从Environmentproperties (属性),添加@ConfigurationProperties添加到其 bean 注册中,如以下示例所示:spring-doc.cadn.net.cn

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class ThirdPartyConfiguration {

	@Bean
	@ConfigurationProperties(prefix = "another")
	public AnotherComponent anotherComponent() {
		return new AnotherComponent();
	}

}

使用anotherprefix 映射到该AnotherComponentbean 以类似于前面的方式SomeProperties例。spring-doc.cadn.net.cn

松散绑定

Spring Boot 使用一些宽松的规则进行绑定Environmentproperties 设置为@ConfigurationPropertiesbeans,因此Environmentproperty name 和 bean property name 的 bean 属性名称。 这有用的常见示例包括以破折号分隔的环境属性(例如context-path绑定到contextPath) 和大写环境属性(例如PORT绑定到port).spring-doc.cadn.net.cn

例如,请考虑以下@ConfigurationProperties类:spring-doc.cadn.net.cn

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "my.main-project.person")
public class MyPersonProperties {

	private String firstName;

	public String getFirstName() {
		return this.firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

}

使用上述代码,可以使用以下属性名称:spring-doc.cadn.net.cn

表 2.松绑
财产 注意

my.main-project.person.first-namespring-doc.cadn.net.cn

烤肉盒,推荐用于.properties和 YAML 文件。spring-doc.cadn.net.cn

my.main-project.person.firstNamespring-doc.cadn.net.cn

标准 Camel 大小写语法。spring-doc.cadn.net.cn

my.main-project.person.first_namespring-doc.cadn.net.cn

下划线表示法,这是.properties和 YAML 文件。spring-doc.cadn.net.cn

MY_MAINPROJECT_PERSON_FIRSTNAMEspring-doc.cadn.net.cn

大写格式,使用系统环境变量时推荐使用。spring-doc.cadn.net.cn

prefix必须采用 kebab 大小写(小写,并用 、 等-my.main-project.person).
表 3.每个属性源的松散绑定规则
Property Source 简单 列表

属性文件spring-doc.cadn.net.cn

驼峰式大小写、kebab 大小写或下划线表示法spring-doc.cadn.net.cn

使用 或 逗号分隔值的标准列表语法[ ]spring-doc.cadn.net.cn

YAML 文件spring-doc.cadn.net.cn

驼峰式大小写、kebab 大小写或下划线表示法spring-doc.cadn.net.cn

标准 YAML 列表语法或逗号分隔值spring-doc.cadn.net.cn

环境变量spring-doc.cadn.net.cn

大写格式,下划线作为分隔符(请参阅从环境变量绑定)。spring-doc.cadn.net.cn

用下划线括起来的数值(请参见从环境变量绑定)spring-doc.cadn.net.cn

系统属性spring-doc.cadn.net.cn

驼峰式大小写、kebab 大小写或下划线表示法spring-doc.cadn.net.cn

使用 或 逗号分隔值的标准列表语法[ ]spring-doc.cadn.net.cn

我们建议尽可能以小写 kebab 格式存储属性,例如my.person.first-name=Rod.

绑定映射

当绑定到Map属性中,你可能需要使用特殊的方括号表示法,以便原始的key值。 如果键未被 、 任何非字母数字字符括起来,或者[]-.被删除。spring-doc.cadn.net.cn

例如,考虑将以下属性绑定到Map<String,String>:spring-doc.cadn.net.cn

my.map[/key1]=value1
my.map[/key2]=value2
my.map./key3=value3
对于 YAML 文件,括号需要用引号括起来,以便正确解析键。

上面的属性将绑定到Map/key1,/key2key3作为映射中的键。 斜杠已从key3因为它没有被方括号包围。spring-doc.cadn.net.cn

当绑定到标量值时,带有.在它们中不需要被 . 标量值包括 enum 和[]java.lang包(除Object. 捆绑a.b=cMap<String, String>将保留.并返回一个 Map,并返回一个 Map,其中包含{"a.b"="c"}. 对于任何其他类型,如果你的key包含一个.. 例如,将a.b=cMap<String, Object>将返回一个 Map,其中包含{"a"={"b"="c"}}[a.b]=c将返回一个 Map,其中包含{"a.b"="c"}.spring-doc.cadn.net.cn

从环境变量绑定

大多数作系统对可用于环境变量的名称施加了严格的规则。 例如,Linux shell 变量只能包含字母 (azAZ)、数字 (09) 或下划线字符 ()。 按照惯例,Unix shell 变量的名称也将采用 UPPERCASE。_spring-doc.cadn.net.cn

Spring Boot 的宽松绑定规则尽可能地设计为与这些命名限制兼容。spring-doc.cadn.net.cn

要将 canonical-form 中的属性名称转换为环境变量名称,您可以遵循以下规则:spring-doc.cadn.net.cn

例如,configuration 属性spring.main.log-startup-info将是名为SPRING_MAIN_LOGSTARTUPINFO.spring-doc.cadn.net.cn

绑定到对象列表时,也可以使用环境变量。 要绑定到List,元素编号应在变量名称中用下划线括起来。spring-doc.cadn.net.cn

例如,configuration 属性my.service[0].other将使用名为MY_SERVICE_0_OTHER.spring-doc.cadn.net.cn

对从环境变量进行绑定的支持应用于systemEnvironmentproperty source 以及名称以-systemEnvironment.spring-doc.cadn.net.cn

从环境变量绑定映射

当 Spring Boot 将环境变量绑定到属性类时,它会在绑定之前将环境变量名称小写。 大多数情况下,这个细节并不重要,除非绑定到Map性能。spring-doc.cadn.net.cn

S 中的 keyMap始终为小写,如以下示例所示:spring-doc.cadn.net.cn

import java.util.HashMap;
import java.util.Map;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "my.props")
public class MyMapsProperties {

	private final Map<String, String> values = new HashMap<>();

	public Map<String, String> getValues() {
		return this.values;
	}

}

设置MY_PROPS_VALUES_KEY=valuevalues Map包含一个{"key"="value"}进入。spring-doc.cadn.net.cn

只有环境变量名称是小写的,而不是值。 设置MY_PROPS_VALUES_KEY=VALUEvalues Map包含一个{"key"="VALUE"}进入。spring-doc.cadn.net.cn

缓存

松散绑定使用缓存来提高性能。默认情况下,此缓存仅应用于不可变属性源。 要自定义此行为,例如为可变属性源启用缓存,请使用ConfigurationPropertyCaching.spring-doc.cadn.net.cn

合并复杂类型

在多个位置配置列表时,覆盖的工作原理是替换整个列表。spring-doc.cadn.net.cn

例如,假设MyPojoobject 替换为namedescription属性null默认情况下。 以下示例公开了MyPojo对象MyProperties:spring-doc.cadn.net.cn

import java.util.ArrayList;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("my")
public class MyProperties {

	private final List<MyPojo> list = new ArrayList<>();

	public List<MyPojo> getList() {
		return this.list;
	}

}

请考虑以下配置:spring-doc.cadn.net.cn

my.list[0].name=my name
my.list[0].description=my description
#---
spring.config.activate.on-profile=dev
my.list[0].name=my another name

如果devprofile 未激活,MyProperties.list包含一个MyPojo条目。 如果dev配置文件,但是,list 仍然只包含一个条目(名称为my another name以及null). 此配置不会添加第二个MyPojo实例添加到列表中,并且不会合并项。spring-doc.cadn.net.cn

List在多个配置文件中指定,则使用优先级最高的配置文件(并且仅使用该配置文件)。 请考虑以下示例:spring-doc.cadn.net.cn

my.list[0].name=my name
my.list[0].description=my description
my.list[1].name=another name
my.list[1].description=another description
#---
spring.config.activate.on-profile=dev
my.list[0].name=my another name

在前面的示例中,如果devprofile 处于活动状态,MyProperties.list包含一个 MyPojo条目(名称为my another name以及null). 对于 YAML,逗号分隔列表和 YAML 列表都可用于完全覆盖列表的内容。spring-doc.cadn.net.cn

Mapproperties 中,您可以与从多个来源提取的属性值绑定。 但是,对于多个来源中的同一属性,将使用优先级最高的属性。 以下示例公开了Map<String, MyPojo>MyProperties:spring-doc.cadn.net.cn

import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("my")
public class MyProperties {

	private final Map<String, MyPojo> map = new LinkedHashMap<>();

	public Map<String, MyPojo> getMap() {
		return this.map;
	}

}

请考虑以下配置:spring-doc.cadn.net.cn

my.map.key1.name=my name 1
my.map.key1.description=my description 1
#---
spring.config.activate.on-profile=dev
my.map.key1.name=dev name 1
my.map.key2.name=dev name 2
my.map.key2.description=dev description 2

如果devprofile 未激活,MyProperties.map包含一个带键的条目key1(名称为my name 1以及my description 1). 如果devprofile 已启用,但是,map包含两个带键的条目key1(名称为dev name 1以及my description 1) 和key2(名称为dev name 2以及dev description 2).spring-doc.cadn.net.cn

上述合并规则适用于所有属性源中的属性,而不仅仅是文件。

属性转换

Spring Boot 在绑定到@ConfigurationProperties豆。 如果需要自定义类型转换,可以提供ConversionServicebean(带有一个名为conversionService) 或自定义属性编辑器(通过CustomEditorConfigurerbean)或自定义转换器(bean 定义注解为@ConfigurationPropertiesBinding).spring-doc.cadn.net.cn

由于此 bean 是在应用程序生命周期的早期请求,因此请确保限制ConversionService正在使用。 通常,您需要的任何依赖项在创建时可能未完全初始化。 您可能希望重命名您的自定义ConversionService如果不需要配置键 强制,并且只依赖限定为@ConfigurationPropertiesBinding.

转换持续时间

Spring Boot 专门支持表示持续时间。 如果您公开了Duration属性,则应用程序属性中的以下格式可用:spring-doc.cadn.net.cn

请考虑以下示例:spring-doc.cadn.net.cn

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.DurationUnit;

@ConfigurationProperties("my")
public class MyProperties {

	@DurationUnit(ChronoUnit.SECONDS)
	private Duration sessionTimeout = Duration.ofSeconds(30);

	private Duration readTimeout = Duration.ofMillis(1000);

	// getters / setters...

	public Duration getSessionTimeout() {
		return this.sessionTimeout;
	}

	public void setSessionTimeout(Duration sessionTimeout) {
		this.sessionTimeout = sessionTimeout;
	}

	public Duration getReadTimeout() {
		return this.readTimeout;
	}

	public void setReadTimeout(Duration readTimeout) {
		this.readTimeout = readTimeout;
	}

}

要指定 30 秒的会话超时,30,PT30S30s都是等效的。 可以采用以下任何形式指定 500 毫秒的读取超时:500,PT0.5S500ms.spring-doc.cadn.net.cn

您还可以使用任何受支持的单位。 这些是:spring-doc.cadn.net.cn

默认单位为毫秒,可以使用@DurationUnit如上面的示例所示。spring-doc.cadn.net.cn

如果您更喜欢使用构造函数绑定,则可以公开相同的属性,如以下示例所示:spring-doc.cadn.net.cn

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.boot.convert.DurationUnit;

@ConfigurationProperties("my")
public class MyProperties {

	// fields...
	private final Duration sessionTimeout;

	private final Duration readTimeout;

	public MyProperties(@DurationUnit(ChronoUnit.SECONDS) @DefaultValue("30s") Duration sessionTimeout,
			@DefaultValue("1000ms") Duration readTimeout) {
		this.sessionTimeout = sessionTimeout;
		this.readTimeout = readTimeout;
	}

	// getters...

	public Duration getSessionTimeout() {
		return this.sessionTimeout;
	}

	public Duration getReadTimeout() {
		return this.readTimeout;
	}

}
如果要升级Long属性,请确保定义单位(使用@DurationUnit) 如果不是毫秒。 这样做提供了透明的升级路径,同时支持更丰富的格式。

转换期间

除了持续时间之外, Spring Boot 还可以使用Period类型。 应用程序属性中可以使用以下格式:spring-doc.cadn.net.cn

简单格式支持以下单位:spring-doc.cadn.net.cn

Periodtype 实际上从未存储过周数,它是一个表示“7 天”的快捷方式。

转换数据大小

Spring Framework 有一个DataSizevalue 类型,以字节为单位表示大小。 如果您公开了DataSize属性,则应用程序属性中的以下格式可用:spring-doc.cadn.net.cn

请考虑以下示例:spring-doc.cadn.net.cn

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.DataSizeUnit;
import org.springframework.util.unit.DataSize;
import org.springframework.util.unit.DataUnit;

@ConfigurationProperties("my")
public class MyProperties {

	@DataSizeUnit(DataUnit.MEGABYTES)
	private DataSize bufferSize = DataSize.ofMegabytes(2);

	private DataSize sizeThreshold = DataSize.ofBytes(512);

	// getters/setters...

	public DataSize getBufferSize() {
		return this.bufferSize;
	}

	public void setBufferSize(DataSize bufferSize) {
		this.bufferSize = bufferSize;
	}

	public DataSize getSizeThreshold() {
		return this.sizeThreshold;
	}

	public void setSizeThreshold(DataSize sizeThreshold) {
		this.sizeThreshold = sizeThreshold;
	}

}

要指定 10 MB 的缓冲区大小,1010MB是等效的。 256 字节的大小阈值可以指定为256256B.spring-doc.cadn.net.cn

您还可以使用任何受支持的单位。 这些是:spring-doc.cadn.net.cn

默认单位为 bytes,可以使用@DataSizeUnit如上面的示例所示。spring-doc.cadn.net.cn

如果您更喜欢使用构造函数绑定,则可以公开相同的属性,如以下示例所示:spring-doc.cadn.net.cn

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.boot.convert.DataSizeUnit;
import org.springframework.util.unit.DataSize;
import org.springframework.util.unit.DataUnit;

@ConfigurationProperties("my")
public class MyProperties {

	// fields...
	private final DataSize bufferSize;

	private final DataSize sizeThreshold;

	public MyProperties(@DataSizeUnit(DataUnit.MEGABYTES) @DefaultValue("2MB") DataSize bufferSize,
			@DefaultValue("512B") DataSize sizeThreshold) {
		this.bufferSize = bufferSize;
		this.sizeThreshold = sizeThreshold;
	}

	// getters...

	public DataSize getBufferSize() {
		return this.bufferSize;
	}

	public DataSize getSizeThreshold() {
		return this.sizeThreshold;
	}

}
如果要升级Long属性,请确保定义单位(使用@DataSizeUnit) 如果不是 bytes。 这样做提供了透明的升级路径,同时支持更丰富的格式。

@ConfigurationProperties验证

Spring Boot 尝试验证@ConfigurationProperties类,只要它们用 Spring 的@Validated注解。 您可以使用 JSR-303jakarta.validationconstraint 注解。 为此,请确保 Classpath 上具有兼容的 JSR-303 实现,然后将约束 Comments 添加到字段中,如以下示例所示:spring-doc.cadn.net.cn

import java.net.InetAddress;

import jakarta.validation.constraints.NotNull;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

@ConfigurationProperties("my.service")
@Validated
public class MyProperties {

	@NotNull
	private InetAddress remoteAddress;

	// getters/setters...

	public InetAddress getRemoteAddress() {
		return this.remoteAddress;
	}

	public void setRemoteAddress(InetAddress remoteAddress) {
		this.remoteAddress = remoteAddress;
	}

}
您还可以通过注释@Bean方法,该方法使用@Validated.

要确保始终为嵌套属性触发验证,即使未找到任何属性,也必须对关联的字段进行批注@Valid. 以下示例基于前面的MyProperties例:spring-doc.cadn.net.cn

import java.net.InetAddress;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

@ConfigurationProperties("my.service")
@Validated
public class MyProperties {

	@NotNull
	private InetAddress remoteAddress;

	@Valid
	private final Security security = new Security();

	// getters/setters...

	public InetAddress getRemoteAddress() {
		return this.remoteAddress;
	}

	public void setRemoteAddress(InetAddress remoteAddress) {
		this.remoteAddress = remoteAddress;
	}

	public Security getSecurity() {
		return this.security;
	}

	public static class Security {

		@NotEmpty
		private String username;

		// getters/setters...

		public String getUsername() {
			return this.username;
		}

		public void setUsername(String username) {
			this.username = username;
		}

	}

}

您还可以添加自定义 SpringValidator通过创建一个名为configurationPropertiesValidator. 这@Beanmethod 应该声明static. 配置属性验证器是在应用程序生命周期的早期创建的,并声明@Bean方法作为 static,则无需实例化@Configuration类。 这样做可以避免早期实例化可能导致的任何问题。spring-doc.cadn.net.cn

spring-boot-actuatormodule 包含一个端点,该端点公开所有@ConfigurationProperties豆。 将 Web 浏览器指向/actuator/configprops或使用等效的 JMX 终端节点。 有关详细信息,请参阅 生产就绪功能 部分。

@ConfigurationProperties vs. @Value

@ValueAnnotation 是容器的核心功能,它不提供与类型安全配置属性相同的功能。 下表总结了 支持 的功能@ConfigurationProperties@Value:spring-doc.cadn.net.cn

特征 @ConfigurationProperties @Value

松散的装订spring-doc.cadn.net.cn

是的spring-doc.cadn.net.cn

受限(请参阅下面的注释)spring-doc.cadn.net.cn

元数据支持spring-doc.cadn.net.cn

是的spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

SpEL评估spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

是的spring-doc.cadn.net.cn

如果您确实想使用@Value,我们建议您使用属性名称的规范形式(kebab 大小写仅使用小写字母)来引用属性名称。 这将允许 Spring Boot 使用与松散绑定时相同的逻辑 @ConfigurationProperties.spring-doc.cadn.net.cn

例如@Value("${demo.item-price}")会接球demo.item-pricedemo.itemPrice表单中application.properties文件以及DEMO_ITEMPRICE从系统环境。 如果您使用了@Value("${demo.itemPrice}")相反demo.item-priceDEMO_ITEMPRICE不会被考虑。spring-doc.cadn.net.cn

如果您为自己的组件定义了一组配置键,我们建议您将它们分组到一个 POJO 中,并带有@ConfigurationProperties. 这样做将为您提供结构化的、类型安全的对象,您可以将其注入到自己的 bean 中。spring-doc.cadn.net.cn

SpEL在解析 Application 属性文件和填充环境时,不会处理这些文件中的表达式。 但是,可以编写SpEL表达式@Value. 如果应用程序属性文件中的属性值是SpELexpression 时,它将在 通过@Value.spring-doc.cadn.net.cn


APP信息