Externalized Configuration
Spring Boot 允许你外部化配置,以便可以在不同的环境中使用相同的应用程序代码。你可以使用各种外部配置源,包括 Java 属性文件、YAML 文件、环境变量和命令行参数。
Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments. You can use a variety of external configuration sources including Java properties files, YAML files, environment variables, and command-line arguments.
可以使用 @Value
批注将属性值直接注入到 Bean 中,通过 Spring 的 Environment
抽象访问,或通过 @ConfigurationProperties
的 bound to structured objects。
Property values can be injected directly into your beans by using the @Value
annotation, accessed through Spring’s Environment
abstraction, or be bound to structured objects through @ConfigurationProperties
.
Spring Boot 使用了一个非常特殊的 PropertySource
顺序,该顺序旨在允许合理地覆盖值。后面的属性源可以覆盖前面定义的值。源按以下顺序考虑:
Spring Boot uses a very particular PropertySource
order that is designed to allow sensible overriding of values.
Later property sources can override the values defined in earlier ones.
Sources are considered in the following order:
-
Default properties (specified by setting
SpringApplication.setDefaultProperties
). -
{url-spring-framework-javadoc}/org/springframework/context/annotation/PropertySource.html[
@PropertySource
] annotations on your@Configuration
classes. Please note that such property sources are not added to theEnvironment
until the application context is being refreshed. This is too late to configure certain properties such aslogging.
andspring.main.
which are read before refresh begins. -
Config data (such as
application.properties
files). -
A
RandomValuePropertySource
that has properties only inrandom.*
. -
OS environment variables.
-
Java System properties (
System.getProperties()
). -
JNDI attributes from
java:comp/env
. -
ServletContext
init parameters. -
ServletConfig
init parameters. -
Properties from
SPRING_APPLICATION_JSON
(inline JSON embedded in an environment variable or system property). -
Command line arguments.
-
properties
attribute on your tests. Available on@SpringBootTest
and the test annotations for testing a particular slice of your application. -
{url-spring-framework-javadoc}/org/springframework/test/context/DynamicPropertySource.html[
@DynamicPropertySource
] annotations in your tests. -
{url-spring-framework-javadoc}/org/springframework/test/context/TestPropertySource.html[
@TestPropertySource
] annotations on your tests. -
Devtools global settings properties in the
$HOME/.config/spring-boot
directory when devtools is active.
配置数据文件按以下顺序考虑:
Config data files are considered in the following order:
-
Application properties packaged inside your jar (
application.properties
and YAML variants). -
Profile-specific application properties packaged inside your jar (
application-{profile}.properties
and YAML variants). -
Application properties outside of your packaged jar (
application.properties
and YAML variants). -
Profile-specific application properties outside of your packaged jar (
application-{profile}.properties
and YAML variants).
建议在整个应用程序中使用一种格式。如果您在同一位置含有 `.properties`和 YAML 格式的配置文件,则 `.properties`优先。 |
It is recommended to stick with one format for your entire application.
If you have configuration files with both |
如果您使用环境变量而不是系统属性,则大多数操作系统不允许使用以句点分隔的键名,不过您可以改用下划线(例如,configprop:spring.config.name[format=envvar] 而不是 configprop:spring.config.name[])。有关详细信息,请参见 Binding From Environment Variables。 |
If you use environment variables rather than system properties, most operating systems disallow period-separated key names, but you can use underscores instead (for example, configprop:spring.config.name[format=envvar] instead of configprop:spring.config.name[]). See Binding From Environment Variables for details. |
如果您的应用程序在 servlet 容器或应用程序服务器中运行,则 JNDI 属性(在 `java:comp/env`中)或 servlet 上下文初始化参数可用于代替环境变量或系统属性,或者与它们一起使用。 |
If your application runs in a servlet container or application server, then JNDI properties (in |
为了提供一个具体的示例,假设您开发一个 @Component
,该 `@Component`使用一个 `name`属性,如下例所示:
To provide a concrete example, suppose you develop a @Component
that uses a name
property, as shown in the following example:
include-code::MyBean[]
在应用程序类路径中(例如,在 jar 内部),您可以有一个 application.properties`文件,该文件为 `name`提供明智的默认属性值。在新的环境中运行时,可以在 jar 外部提供一个 `application.properties`文件,该文件覆盖 `name
。对于一次性测试,您可以使用特定命令行开关启动(例如,java -jar app.jar --name="Spring"
)。
On your application classpath (for example, inside your jar) you can have an application.properties
file that provides a sensible default property value for name
.
When running in a new environment, an application.properties
file can be provided outside of your jar that overrides the name
.
For one-off testing, you can launch with a specific command line switch (for example, java -jar app.jar --name="Spring"
).
`env`和 `configprops`端点可用于确定属性具有特定值的原因。您可以使用这两个端点来诊断意外的属性值。有关详细信息,请参见“Production ready features”部分。 |
The |
Accessing Command Line Properties
默认情况下,SpringApplication`将任何命令行选项参数(即以 `--`开头的参数,例如 `--server.port=9000
)转换为一个 property
,然后将它们添加到 Spring Environment
。如前所述,命令行属性始终优先于基于文件的属性源。
By default, SpringApplication
converts any command line option arguments (that is, arguments starting with --
, such as --server.port=9000
) to a property
and adds them to the Spring Environment
.
As mentioned previously, command line properties always take precedence over file-based property sources.
如果您不希望命令行属性添加到 Environment
,则可以使用 `SpringApplication.setAddCommandLineProperties(false)`禁用它们。
If you do not want command line properties to be added to the Environment
, you can disable them by using SpringApplication.setAddCommandLineProperties(false)
.
JSON Application Properties
环境变量和系统属性通常有受限,这意味着无法使用某些属性名称。为了解决此问题,Spring Boot 允许您将属性块编码到一个 JSON 结构中。
Environment variables and system properties often have restrictions that mean some property names cannot be used. To help with this, Spring Boot allows you to encode a block of properties into a single JSON structure.
当您的应用程序启动时,所有 spring.application.json`或 `SPRING_APPLICATION_JSON`属性都将被解析并添加到 `Environment
。
When your application starts, any spring.application.json
or SPRING_APPLICATION_JSON
properties will be parsed and added to the Environment
.
例如,`SPRING_APPLICATION_JSON`属性可在 UN*X shell 中作为环境变量在命令行上提供:
For example, the SPRING_APPLICATION_JSON
property can be supplied on the command line in a UN*X shell as an environment variable:
$ SPRING_APPLICATION_JSON='{"my":{"name":"test"}}' java -jar myapp.jar
在下例中,最终得到 Spring 中的 my.name=test
。
In the preceding example, you end up with my.name=test
in the Spring Environment
.
同样,JSON 也可以作为一个系统属性提供:
The same JSON can also be provided as a system property:
$ java -Dspring.application.json='{"my":{"name":"test"}}' -jar myapp.jar
或者可以使用命令行参数提供 JSON:
Or you could supply the JSON by using a command line argument:
$ java -jar myapp.jar --spring.application.json='{"my":{"name":"test"}}'
如果要部署到经典应用程序服务器,也可以使用名为 java:comp/env/spring.application.json
的 JNDI 变量。
If you are deploying to a classic Application Server, you could also use a JNDI variable named java:comp/env/spring.application.json
.
尽管 JSON 中的 |
Although |
External Application Properties
应用程序启动时,Spring Boot 将自动查找并加载以下位置中的 application.properties
和 application.yaml
文件:
Spring Boot will automatically find and load application.properties
and application.yaml
files from the following locations when your application starts:
-
From the classpath[style="loweralpha"]
-
The classpath root
-
The classpath
/config
package
-
-
From the current directory[style="loweralpha"]
-
The current directory
-
The
config/
subdirectory in the current directory -
Immediate child directories of the
config/
subdirectory
-
该列表按优先级排序(较低项中的值覆盖较早项)。加载的文件中的文档以 PropertySources
形式添加到 Spring Environment
中。
The list is ordered by precedence (with values from lower items overriding earlier ones).
Documents from the loaded files are added as PropertySources
to the Spring Environment
.
如果不希望将 application
作为配置文件的名称,可以通过指定 configprop:spring.config.name[] 环境属性切换到其他文件名。例如,要查找 myproject.properties
和 myproject.yaml
文件,可以按如下方式运行应用程序:
If you do not like application
as the configuration file name, you can switch to another file name by specifying a configprop:spring.config.name[] environment property.
For example, to look for myproject.properties
and myproject.yaml
files you can run your application as follows:
$ java -jar myproject.jar --spring.config.name=myproject
还可以通过使用 configprop:spring.config.location[] 环境属性引用显式位置。该属性接受一个或多个要检查位置的逗号分隔列表。
You can also refer to an explicit location by using the configprop:spring.config.location[] environment property. This property accepts a comma-separated list of one or more locations to check.
以下示例显示如何指定两份不同的文件:
The following example shows how to specify two distinct files:
$ java -jar myproject.jar --spring.config.location=\
optional:classpath:/default.properties,\
optional:classpath:/override.properties
如果存在 locations are optional ,可以使用前缀 |
Use the prefix |
非常早地使用 spring.config.name
、spring.config.location
和 spring.config.additional-location
来确定要加载哪些文件。必须将它们定义为环境属性(通常是操作系统环境变量、系统属性或命令行参数)。
spring.config.name
, spring.config.location
, and spring.config.additional-location
are used very early to determine which files have to be loaded.
They must be defined as an environment property (typically an OS environment variable, a system property, or a command-line argument).
如果 spring.config.location
包含目录(而不是文件),它们应以 /
结尾。在加载之前,将在运行时将它们追加到从 spring.config.name
生成的名称。spring.config.location
中指定的文件会被直接导入。
If spring.config.location
contains directories (as opposed to files), they should end in /
.
At runtime they will be appended with the names generated from spring.config.name
before being loaded.
Files specified in spring.config.location
are imported directly.
目录和文件位置值都会被展开以检查 profile-specific files 。例如,如果 |
Both directory and file location values are also expanded to check for profile-specific files.
For example, if you have a |
在大多数情况下,添加的每个 configprop:spring.config.location[] 项都会引用单个文件或目录。位置按指定的顺序进行处理,后面的位置可以覆盖前面的位置。
In most situations, each configprop:spring.config.location[] item you add will reference a single file or directory. Locations are processed in the order that they are defined and later ones can override the values of earlier ones.
如果有复杂的位置设置,并且使用特定于配置文件,则可能需要提供更多提示,以便 Spring Boot 知道应该如何将它们分组。位置组是同一级别所有位置的集合。例如,可能希望对所有类路径位置进行分组,然后对所有外部位置进行分组。位置组中的项应以 ;
分隔。有关更多详细信息,请参阅 “Profile Specific Files” 部分中的示例。
If you have a complex location setup, and you use profile-specific configuration files, you may need to provide further hints so that Spring Boot knows how they should be grouped.
A location group is a collection of locations that are all considered at the same level.
For example, you might want to group all classpath locations, then all external locations.
Items within a location group should be separated with ;
.
See the example in the “Profile Specific Files” section for more details.
使用 spring.config.location
配置的位置会替换默认位置。例如,如果将 spring.config.location
配置为值 optional:classpath:/custom-config/,optional:file:./custom-config/
,那么考虑的位置的完整集合是:
Locations configured by using spring.config.location
replace the default locations.
For example, if spring.config.location
is configured with the value optional:classpath:/custom-config/,optional:file:./custom-config/
, the complete set of locations considered is:
-
optional:classpath:custom-config/
-
optional:file:./custom-config/
如果你希望添加其他位置,而不是替换它们,则可以使用 spring.config.additional-location
。从其他位置加载的属性可以覆盖默认位置中的属性。例如,如果配置的 spring.config.additional-location
值为 optional:classpath:/custom-config/,optional:file:./custom-config/
,考虑的位置的完整集合为:
If you prefer to add additional locations, rather than replacing them, you can use spring.config.additional-location
.
Properties loaded from additional locations can override those in the default locations.
For example, if spring.config.additional-location
is configured with the value optional:classpath:/custom-config/,optional:file:./custom-config/
, the complete set of locations considered is:
-
optional:classpath:/;optional:classpath:/config/
-
optional:file:./;optional:file:./config/;optional:file:./config/*/
-
optional:classpath:custom-config/
-
optional:file:./custom-config/
此搜索顺序允许你在一个配置文件中指定默认值,然后在另一个配置文件中选择性重写这些值。你可以在默认位置之一中(或使用 spring.config.name
选择的任何其他基本名称)的 application.properties
(或使用 spring.config.name
选择的任何其他基本名称)中为你的应用程序提供默认值。然后可以使用位于自定义位置之一中的不同文件在运行时覆盖这些默认值。
This search ordering lets you specify default values in one configuration file and then selectively override those values in another.
You can provide default values for your application in application.properties
(or whatever other basename you choose with spring.config.name
) in one of the default locations.
These default values can then be overridden at runtime with a different file located in one of the custom locations.
Optional Locations
默认情况下,当指定的配置数据位置不存在时,Spring Boot 将抛出一个 ConfigDataLocationNotFoundException
,并且你的应用程序将不会启动。
By default, when a specified config data location does not exist, Spring Boot will throw a ConfigDataLocationNotFoundException
and your application will not start.
如果你想指定一个位置,但你不介意它是否一直存在,则可以使用 optional:
前缀。你可以在 spring.config.location
和 spring.config.additional-location
属性以及 spring.config.import
声明中使用此前缀。
If you want to specify a location, but you do not mind if it does not always exist, you can use the optional:
prefix.
You can use this prefix with the spring.config.location
and spring.config.additional-location
properties, as well as with spring.config.import
declarations.
例如,即使不存在 myconfig.properties
文件,spring.config.import
值为 optional:file:./myconfig.properties
也可以允许你的应用程序启动。
For example, a spring.config.import
value of optional:file:./myconfig.properties
allows your application to start, even if the myconfig.properties
file is missing.
如果你想要忽略所有 ConfigDataLocationNotFoundExceptions
并始终继续启动你的应用程序,你可以使用 spring.config.on-not-found
属性。使用 SpringApplication.setDefaultProperties(…)
或通过系统/环境变量将值设置为 ignore
。
If you want to ignore all ConfigDataLocationNotFoundExceptions
and always continue to start your application, you can use the spring.config.on-not-found
property.
Set the value to ignore
using SpringApplication.setDefaultProperties(…)
or with a system/environment variable.
Wildcard Locations
如果配置文件位置包含最后一个路径段的 *
字符,它会被视为通配符位置。通配符会在加载配置时展开,以便也检查立即子目录。当存在多种配置属性源时,诸如 Kubernetes 之类的环境中会特别有用通配符位置。
If a config file location includes the *
character for the last path segment, it is considered a wildcard location.
Wildcards are expanded when the config is loaded so that immediate subdirectories are also checked.
Wildcard locations are particularly useful in an environment such as Kubernetes when there are multiple sources of config properties.
例如,如果你有一些 Redis 配置和一些 MySQL 配置,你可能想要将这两部分配置分开,同时要求两者都存在于 application.properties
文件中。这可能会导致两个单独的 application.properties
文件挂载在不同的位置,例如 /config/redis/application.properties
和 /config/mysql/application.properties
。在这种情况下,拥有 config/*/
的通配符位置将导致处理这两个文件。
For example, if you have some Redis configuration and some MySQL configuration, you might want to keep those two pieces of configuration separate, while requiring that both those are present in an application.properties
file.
This might result in two separate application.properties
files mounted at different locations such as /config/redis/application.properties
and /config/mysql/application.properties
.
In such a case, having a wildcard location of config/*/
, will result in both files being processed.
默认情况下,Spring Boot 在默认搜索位置中包括 config/*/
。这意味着将搜索 jar 外部 /config
目录的所有子目录。
By default, Spring Boot includes config/*/
in the default search locations.
It means that all subdirectories of the /config
directory outside of your jar will be searched.
你可以自己使用 spring.config.location
和 spring.config.additional-location
属性使用通配符位置。
You can use wildcard locations yourself with the spring.config.location
and spring.config.additional-location
properties.
通配符位置对于作为目录的搜索位置只包含一个 |
A wildcard location must contain only one |
通配符位置仅适用于外部目录。你不能在 |
Wildcard locations only work with external directories.
You cannot use a wildcard in a |
Profile Specific Files
除了 application
属性文件之外,Spring Boot 还会尝试使用命名约定 application-{profile}
加载特定于概要的文件。例如,如果你的应用程序激活了名为 prod
的概要并使用了 YAML 文件,那么 application.yaml
和 application-prod.yaml
都将被考虑。
As well as application
property files, Spring Boot will also attempt to load profile-specific files using the naming convention application-{profile}
.
For example, if your application activates a profile named prod
and uses YAML files, then both application.yaml
and application-prod.yaml
will be considered.
特定于概要的属性从与标准 application.properties
相同的位置加载,其中特定于概要的文件始终覆盖非特定于概要的文件。如果指定了多个概要,则应用“最近者优先”策略。例如,如果通过 configprop:spring.profiles.active[] 属性指定了概要 prod,live
,则 application-prod.properties
中的值可以被 application-live.properties
中的值覆盖。
Profile-specific properties are loaded from the same locations as standard application.properties
, with profile-specific files always overriding the non-specific ones.
If several profiles are specified, a last-wins strategy applies.
For example, if profiles prod,live
are specified by the configprop:spring.profiles.active[] property, values in application-prod.properties
can be overridden by those in application-live.properties
.
“最近者优先”策略在 location group 级别应用。 The last-wins strategy applies at the location group level.
A configprop:spring.config.location[] of 例如,在继续上述我们的 For example, continuing our /cfg application-live.properties /ext application-live.properties application-prod.properties 当我们有 configprop:spring.config.location[] 时,在所有 When we have a configprop:spring.config.location[] of
当我们反而有 When we have
|
如果未设置任何活动概要,Environment
有一组默认概要(默认情况下为 [default]
)。换言之,如果没有明确激活任何概要,则会考虑 application-default
中的属性。
The Environment
has a set of default profiles (by default, [default]
) that are used if no active profiles are set.
In other words, if no profiles are explicitly activated, then properties from application-default
are considered.
属性文件只会加载一次。如果你已经直接 imported 了特定于概要的属性文件,则不会再次导入它。 |
Properties files are only ever loaded once. If you have already directly imported a profile specific property files then it will not be imported a second time. |
Importing Additional Data
应用程序属性可以使用 spring.config.import
属性从其他位置导入更多配置数据。导入在被发现时处理,并被视为立即在声明导入的位置下方插入的附加文档。
Application properties may import further config data from other locations using the spring.config.import
property.
Imports are processed as they are discovered, and are treated as additional documents inserted immediately below the one that declares the import.
例如,你可能在 classpath application.properties
文件中拥有以下内容:
For example, you might have the following in your classpath application.properties
file:
spring: application: name: "myapp" config: import: "optional:file:./dev.properties"
这将触发从当前目录中导入一个 dev.properties
文件(如果存在此文件)。导入的 dev.properties
的值将优先于触发导入的文件。在上面的示例中,dev.properties
可以将 spring.application.name
重新定义为一个不同的值。
This will trigger the import of a dev.properties
file in current directory (if such a file exists).
Values from the imported dev.properties
will take precedence over the file that triggered the import.
In the above example, the dev.properties
could redefine spring.application.name
to a different value.
无论声明次数如何,导入只导入一次。导入在一个文档内部的 properties/yaml 文件中的定义顺序无关紧要。例如,下面的两个示例生成相同的结果:
An import will only be imported once no matter how many times it is declared. The order an import is defined inside a single document within the properties/yaml file does not matter. For instance, the two examples below produce the same result:
spring: config: import: "my.properties" my: property: "value"
my: property: "value" spring: config: import: "my.properties"
在上面的两个示例中,my.properties
文件中的值将优先于触发其导入的文件。
In both of the above examples, the values from the my.properties
file will take precedence over the file that triggered its import.
多个位置可以指定在一个 spring.config.import
键下。位置将按照它们定义的顺序处理,其中后面的导入优先。
Several locations can be specified under a single spring.config.import
key.
Locations will be processed in the order that they are defined, with later imports taking precedence.
在适当的时候,Profile-specific variants 也考虑进行导入。上面的示例将导入 |
When appropriate, Profile-specific variants are also considered for import.
The example above would import both |
Spring Boot 包括可插入 API,该 API 支持各种不同的位置地址。默认情况下,您可以导入 Java 属性、YAML 和 “configuration trees”。 Spring Boot includes pluggable API that allows various different location addresses to be supported. By default you can import Java Properties, YAML and “configuration trees”. 第三方 jar 可以为额外的技术提供支持(文件不必是本地的,没有此项要求)。例如,您可以想象外部存储(例如 Consul、Apache ZooKeeper 或 Netflix Archaius)中的配置数据。 Third-party jars can offer support for additional technologies (there is no requirement for files to be local). For example, you can imagine config data being from external stores such as Consul, Apache ZooKeeper or Netflix Archaius. 如果您想支持您自己的位置,请查看 If you want to support your own locations, see the |
Importing Extensionless Files
一些云平台无法为已装载的文件添加文件扩展名。要导入这些没有扩展名的文件,你需要向 Spring Boot 提供一个提示,以便它知道如何加载它们。你可以通过在方括号中放置扩展名提示来执行此操作。
Some cloud platforms cannot add a file extension to volume mounted files. To import these extensionless files, you need to give Spring Boot a hint so that it knows how to load them. You can do this by putting an extension hint in square brackets.
例如,假设你有希望导入为 yaml 的 s0 文件。你可以使用以下命令从 s1 导入它:
For example, suppose you have a /etc/config/myconfig
file that you wish to import as yaml.
You can import it from your application.properties
using the following:
spring: config: import: "file:/etc/config/myconfig[.yaml]"
Using Configuration Trees
在云平台(例如 Kubernetes)上运行应用程序时,你通常需要读取平台提供的配置值。为此目的使用环境变量很常见,但这可能存在缺陷,尤其是在该值应保密时。
When running applications on a cloud platform (such as Kubernetes) you often need to read config values that the platform supplies. It is not uncommon to use environment variables for such purposes, but this can have drawbacks, especially if the value is supposed to be kept secret.
作为环境变量的替代方案,许多云平台现在允许你将配置映射到已装载的数据卷。例如,Kubernetes 可以卷装载 s4 和 s5。
As an alternative to environment variables, many cloud platforms now allow you to map configuration into mounted data volumes.
For example, Kubernetes can volume mount both ConfigMaps
and Secrets
.
可以使用两种常见的卷装载模式:
There are two common volume mount patterns that can be used:
-
A single file contains a complete set of properties (usually written as YAML).
-
Multiple files are written to a directory tree, with the filename becoming the '`key’ and the contents becoming the '`value’.
对于第一个案例,您可以直接使用 `spring.config.import`导入 YAML 或 Properties 文件,如 above中所述。对于第二个案例,您需要使用 `configtree:`前缀,以便 Spring Boot 知道它需要公开所有文件作为属性。
For the first case, you can import the YAML or Properties file directly using spring.config.import
as described above.
For the second case, you need to use the configtree:
prefix so that Spring Boot knows it needs to expose all the files as properties.
例如,让我们想象一下 Kubernetes 挂载了以下卷:
As an example, let’s imagine that Kubernetes has mounted the following volume:
etc/
config/
myapp/
username
password
`username`文件的内容将是 config 值,而 `password`的内容将是机密。
The contents of the username
file would be a config value, and the contents of password
would be a secret.
要导入这些属性,您可以将以下内容添加到您的 `application.properties`或 `application.yaml`文件中:
To import these properties, you can add the following to your application.properties
or application.yaml
file:
spring: config: import: "optional:configtree:/etc/config/"
然后,您可以通过 `Environment`以通常的方式访问或注入 `myapp.username`和 `myapp.password`属性。
You can then access or inject myapp.username
and myapp.password
properties from the Environment
in the usual way.
config 树下的文件夹和文件名称构成了属性名称。在上面的示例中,要以 |
The names of the folders and files under the config tree form the property name.
In the above example, to access the properties as |
带点表示法的文件名也正确地映射了。例如,在上面的示例中,`/etc/config`中的名为 `myapp.username`的文件将在 `Environment`中产生一个 `myapp.username`属性。 |
Filenames with dot notation are also correctly mapped.
For example, in the above example, a file named |
根据预期的内容,Configuration 树值可以绑定到字符串 `String`和 `byte[]`类型。 |
Configuration tree values can be bound to both string |
如果您有多个 config 树要从同一个父文件夹导入,可以使用通配符快捷方式。任何以 `/*/`结尾的 `configtree:`位置都将导入所有直接子级作为 config 树。与非通配符导入一样,每个 config 树下的文件夹和文件名称构成了属性名称。
If you have multiple config trees to import from the same parent folder you can use a wildcard shortcut.
Any configtree:
location that ends with /*/
will import all immediate children as config trees.
As with a non-wildcard import, the names of the folders and files under each config tree form the property name.
例如,给定以下卷:
For example, given the following volume:
etc/
config/
dbconfig/
db/
username
password
mqconfig/
mq/
username
password
您可以使用 `configtree:/etc/config/*/`作为导入位置:
You can use configtree:/etc/config/*/
as the import location:
spring: config: import: "optional:configtree:/etc/config/*/"
这将添加 db.username
、db.password
、`mq.username`和 `mq.password`属性。
This will add db.username
, db.password
, mq.username
and mq.password
properties.
使用通配符加载的目录按字母顺序排序。如果您需要不同的顺序,则应将每个位置列为单独的导入 |
Directories loaded using a wildcard are sorted alphabetically. If you need a different order, then you should list each location as a separate import |
Configuration 树也可以用于 Docker 机密。当 Docker 群集服务被授予访问机密的权限时,机密会被装载到容器中。例如,如果在位置 `/run/secrets/`上装载了一个名为 `db.password`的机密,则可以使用以下内容使 `db.password`可用于 Spring 环境:
Configuration trees can also be used for Docker secrets.
When a Docker swarm service is granted access to a secret, the secret gets mounted into the container.
For example, if a secret named db.password
is mounted at location /run/secrets/
, you can make db.password
available to the Spring environment using the following:
spring: config: import: "optional:configtree:/run/secrets/"
Property Placeholders
application.properties`和 `application.yaml`中的值在使用时将通过现有的 `Environment`进行过滤,因此您可以返回到先前定义的值(例如,来自系统属性或环境变量)。标准 `${name}`属性占位符语法可以在值中的任何位置使用。属性占位符还可以使用 `:`指定默认值,以将默认值与属性名称分开,例如 `${name:default}
。
The values in application.properties
and application.yaml
are filtered through the existing Environment
when they are used, so you can refer back to previously defined values (for example, from System properties or environment variables).
The standard ${name}
property-placeholder syntax can be used anywhere within a value.
Property placeholders can also specify a default value using a :
to separate the default value from the property name, for example ${name:default}
.
以下示例显示了带或不带默认值使用占位符的情况:
The use of placeholders with and without defaults is shown in the following example:
app: name: "MyApp" description: "${app.name} is a Spring Boot application written by ${username:Unknown}"
假设 username`属性尚未在其他地方设置,则 `app.description`将具有值 `MyApp is a Spring Boot application written by Unknown
。
Assuming that the username
property has not been set elsewhere, app.description
will have the value MyApp is a Spring Boot application written by Unknown
.
您应该始终使用规范形式(仅使用小写字母的 kebab-case)在占位符中引用属性名称。这将允许 Spring Boot 使用与处理 relaxed binding`@ConfigurationProperties`时相同的逻辑。 You should always refer to property names in the placeholder using their canonical form (kebab-case using only lowercase letters).
This will allow Spring Boot to use the same logic as it does when relaxed binding 例如, For example, |
还可以使用这种技术创建现有 Spring Boot 属性的 “short” 变体。请参阅 Use '`Short’ Command Line Arguments 了解详情。 |
You can also use this technique to create “short” variants of existing Spring Boot properties. See the Use '`Short’ Command Line Arguments how-to for details. |
Working With Multi-Document Files
Spring Boot 允许将一个物理文件拆分为多个独立添加的逻辑文档。按从上到下的顺序处理文档。后面的文档可以覆盖早期文档中定义的属性。
Spring Boot allows you to split a single physical file into multiple logical documents which are each added independently. Documents are processed in order, from top to bottom. Later documents can override the properties defined in earlier ones.
对于 application.yaml
文件,使用标准 YAML 多文档语法。三个连续连字符表示一个文档的结尾和下一个文档的开头。
For application.yaml
files, the standard YAML multi-document syntax is used.
Three consecutive hyphens represent the end of one document, and the start of the next.
例如,以下文件有两个逻辑文档:
For example, the following file has two logical documents:
spring:
application:
name: "MyApp"
---
spring:
application:
name: "MyCloudApp"
config:
activate:
on-cloud-platform: "kubernetes"
对于 application.properties
文件,使用特殊的 #---
或 !---
注释来标记文档拆分:
For application.properties
files a special #---
or !---
comment is used to mark the document splits:
spring.application.name=MyApp
#---
spring.application.name=MyCloudApp
spring.config.activate.on-cloud-platform=kubernetes
属性文件分隔符前面不能有任何空格,并且必须有恰好三个连字符。分隔符之前和之后的行不能相同注释前缀。 |
Property file separators must not have any leading whitespace and must have exactly three hyphen characters. The lines immediately before and after the separator must not be same comment prefix. |
多文档属性文件通常与激活属性(如 |
Multi-document property files are often used in conjunction with activation properties such as |
无法使用 @PropertySource
或 @TestPropertySource
注释加载多文档属性文件。
Multi-document property files cannot be loaded by using the @PropertySource
or @TestPropertySource
annotations.
Activation Properties
有时仅在满足特定条件时激活给定的属性集是很有用的。例如,可以具备仅在特定配置文件处于活动状态时才相关的属性。
It is sometimes useful to only activate a given set of properties when certain conditions are met. For example, you might have properties that are only relevant when a specific profile is active.
可以使用 spring.config.activate.*
根据条件激活属性文档。
You can conditionally activate a properties document using spring.config.activate.*
.
以下激活属性可用:
The following activation properties are available:
Property | Note |
---|---|
|
A profile expression that must match for the document to be active. |
|
The |
例如,以下指定第二个文档仅在 Kubernetes 上运行时处于活动状态,并且仅当 “prod” 或 “staging” 配置文件处于活动状态时:
For example, the following specifies that the second document is only active when running on Kubernetes, and only when either the “prod” or “staging” profiles are active:
myprop: "always-set" --- spring: config: activate: on-cloud-platform: "kubernetes" on-profile: "prod | staging" myotherprop: "sometimes-set"
Encrypting Properties
Spring Boot 不提供任何内置支持来加密属性值,但是,它确实提供了必要的挂钩点来修改包含在 Spring Environment
中的值。在应用程序启动之前,EnvironmentPostProcessor
接口允许操作 Environment
。有关详细信息,请参阅 Customize the Environment or ApplicationContext Before It Starts。
Spring Boot does not provide any built-in support for encrypting property values, however, it does provide the hook points necessary to modify values contained in the Spring Environment
.
The EnvironmentPostProcessor
interface allows you to manipulate the Environment
before the application starts.
See Customize the Environment or ApplicationContext Before It Starts for details.
如果需要安全的方式来存储凭证和密码, Spring Cloud Vault 项目将提供将外部配置存储在 HashiCorp Vault 中的支持。
If you need a secure way to store credentials and passwords, the Spring Cloud Vault project provides support for storing externalized configuration in HashiCorp Vault.
Working With YAML
YAML is a superset of JSON and, as such, is a convenient format for specifying hierarchical configuration data.
The SpringApplication
class automatically supports YAML as an alternative to properties whenever you have the SnakeYAML library on your classpath.
如果您使用 “Starters”, |
If you use “Starters”, SnakeYAML is automatically provided by |
Mapping YAML to Properties
YAML 文档需要从其分层格式转换为可以用 Spring Environment
使用的平面结构。例如,考虑以下 YAML 文档:
YAML documents need to be converted from their hierarchical format to a flat structure that can be used with the Spring Environment
.
For example, consider the following YAML document:
environments:
dev:
url: "https://dev.example.com"
name: "Developer Setup"
prod:
url: "https://another.example.com"
name: "My Cool App"
为了从 Environment
访问这些属性,它们会被展平如下:
In order to access these properties from the Environment
, they would be flattened as follows:
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]
解引用器的属性键。例如,考虑以下 YAML:
Likewise, YAML lists also need to be flattened.
They are represented as property keys with [index]
dereferencers.
For example, consider the following YAML:
my:
servers:
- "dev.example.com"
- "another.example.com"
前面对例将被转换为以下属性:
The preceding example would be transformed into these properties:
my.servers[0]=dev.example.com
my.servers[1]=another.example.com
使用 |
Properties that use the |
YAML 文件不能使用 @PropertySource
或 @TestPropertySource
注释加载。因此,如果您需要以这种方式加载值,则需要使用属性文件。
YAML files cannot be loaded by using the @PropertySource
or @TestPropertySource
annotations.
So, in the case that you need to load values that way, you need to use a properties file.
Directly Loading YAML
Spring Framework 提供了两个方便的类,可以用来加载 YAML 文档。YamlPropertiesFactoryBean
将 YAML 作为 Properties
加载,而 YamlMapFactoryBean
将 YAML 作为 Map
加载。
Spring Framework provides two convenient classes that can be used to load YAML documents.
The YamlPropertiesFactoryBean
loads YAML as Properties
and the YamlMapFactoryBean
loads YAML as a Map
.
如果您想将 YAML 作为 Spring PropertySource
加载,您也可以使用 YamlPropertySourceLoader
类。
You can also use the YamlPropertySourceLoader
class if you want to load YAML as a Spring PropertySource
.
Configuring Random Values
RandomValuePropertySource
对于注入随机值(例如注入到机密或测试案例中)很有用。它可以生成整数、长整数、UUID 或字符串,如下例所示:
The RandomValuePropertySource
is useful for injecting random values (for example, into secrets or test cases).
It can produce integers, longs, uuids, or strings, as shown in the following example:
my: secret: "${random.value}" number: "${random.int}" bignumber: "${random.long}" uuid: "${random.uuid}" number-less-than-ten: "${random.int(10)}" number-in-range: "${random.int[1024,65536]}"
random.int*
语法是 OPEN value (,max) CLOSE
,其中 OPEN,CLOSE
是任意字符, value,max
是整数。如果提供了 max
,则 value
是最小值, max
是最大值(不包括)。
The random.int*
syntax is OPEN value (,max) CLOSE
where the OPEN,CLOSE
are any character and value,max
are integers.
If max
is provided, then value
is the minimum value and max
is the maximum value (exclusive).
Configuring System Environment Properties
Spring Boot 支持为环境属性设置前缀。如果系统环境由多个 Spring Boot 应用程序共享,并且这些应用程序具有不同的配置要求,此功能非常有用。系统环境属性的前缀可以在 SpringApplication
上直接设置。
Spring Boot supports setting a prefix for environment properties.
This is useful if the system environment is shared by multiple Spring Boot applications with different configuration requirements.
The prefix for system environment properties can be set directly on SpringApplication
.
例如,如果您将前缀设置为 input
,则诸如 remote.timeout
的属性也会在系统环境中解析为 input.remote.timeout
。
For example, if you set the prefix to input
, a property such as remote.timeout
will also be resolved as input.remote.timeout
in the system environment.
Type-safe Configuration Properties
使用 @Value("${property}")
注释注入配置属性有时会很麻烦,尤其是在处理多属性或数据本质上是分层的情况下。Spring Boot 提供了一种处理属性的替代方法,该方法允许经过强类型处理的 Bean 管理和验证应用程序的配置。
Using the @Value("${property}")
annotation to inject configuration properties can sometimes be cumbersome, especially if you are working with multiple properties or your data is hierarchical in nature.
Spring Boot provides an alternative method of working with properties that lets strongly typed beans govern and validate the configuration of your application.
JavaBean Properties Binding
可以绑定一个声明标准 JavaBean 属性的 Bean,如下例所示:
It is possible to bind a bean declaring standard JavaBean properties as shown in the following example:
前述 POJO 定义了以下属性:
The preceding POJO defines the following properties:
-
my.service.enabled
, with a value offalse
by default. -
my.service.remote-address
, with a type that can be coerced fromString
. -
my.service.security.username
, with a nested "security" object whose name is determined by the name of the property. In particular, the type is not used at all there and could have beenSecurityProperties
. -
my.service.security.password
. -
my.service.security.roles
, with a collection ofString
that defaults toUSER
.
映射到 Spring Boot 中可用的 s11 类的属性(通过属性文件、YAML 文件、环境变量和其他机制进行配置)是公开 API,但该类的访问器(getter/setter)本身不用于直接使用。 |
The properties that map to |
这种安排依赖于默认的空构造函数,而 getter 和 setter 通常是强制性的,因为绑定是通过标准 Java Beans 属性描述符进行的,就像在 Spring MVC 中一样。在以下情况下可以省略 setter: Such arrangement relies on a default empty constructor and getters and setters are usually mandatory, since binding is through standard Java Beans property descriptors, just like in Spring MVC. A setter may be omitted in the following cases:
有些人使用 Project Lombok 自动添加获取器和设置器。请确保 Lombok 不针对此类类型生成任何特定构造函数,因为容器会自动使用它实例化对象。 Some people use Project Lombok to add getters and setters automatically. Make sure that Lombok does not generate any particular constructor for such a type, as it is used automatically by the container to instantiate the object. 最后,只考虑标准 Java Bean 属性,并且不支持静态属性上的绑定。 Finally, only standard Java Bean properties are considered and binding on static properties is not supported. |
Constructor Binding
前一节中的示例可以用不可变的方式改写,如下例所示:
The example in the previous section can be rewritten in an immutable fashion as shown in the following example:
在此设置中,存在一个单参数化构造函数暗示应使用构造函数绑定。这意味着绑定器将找到具有您希望绑定的参数的构造函数。如果您的类具有多个构造函数,则 @ConstructorBinding
注解可用于指定应针对构造函数绑定使用哪个构造函数。要选择不为具有单个参数化构造函数的类进行构造函数绑定,必须使用 @Autowired
注解构造函数。构造函数绑定可用于记录。除非记录有多个构造函数,否则无需使用 @ConstructorBinding
。
In this setup, the presence of a single parameterized constructor implies that constructor binding should be used.
This means that the binder will find a constructor with the parameters that you wish to have bound.
If your class has multiple constructors, the @ConstructorBinding
annotation can be used to specify which constructor to use for constructor binding.
To opt out of constructor binding for a class with a single parameterized constructor, the constructor must be annotated with @Autowired
.
Constructor binding can be used with records.
Unless your record has multiple constructors, there is no need to use @ConstructorBinding
.
构造函数绑定类的嵌套成员(如上述示例中的 Security
)也将通过其构造函数进行绑定。
Nested members of a constructor bound class (such as Security
in the example above) will also be bound through their constructor.
可以使用 @DefaultValue
在构造函数参数和记录组件上指定默认值。转换服务将应用于强制转换批注的 String
值为缺少属性的目标类型。
Default values can be specified using @DefaultValue
on constructor parameters and record components.
The conversion service will be applied to coerce the annotation’s String
value to the target type of a missing property.
参考前一个示例,如果没有任何属性绑定到 Security
,则 MyProperties
实例将包含 security
的 null
值。为了使其包含一个非空 Security
实例,即使没有任何属性绑定到它(当使用 Kotlin 时,这要求 Security
的 username
和 password
参数被声明为可为空的,因为它们没有默认值),请使用 @DefaultValue
空注解:
Referring to the previous example, if no properties are bound to Security
, the MyProperties
instance will contain a null
value for security
.
To make it contain a non-null instance of Security
even when no properties are bound to it (when using Kotlin, this will require the username
and password
parameters of Security
to be declared as nullable as they do not have default values), use an empty @DefaultValue
annotation:
要使用构造函数绑定,必须使用 |
To use constructor binding the class must be enabled using |
要在本机映像中使用构造函数绑定,必须使用 |
To use constructor binding in a native image the class must be compiled with |
不建议将 |
The use of |
Enabling @ConfigurationProperties-annotated Types
Spring Boot 提供基础设施,用于绑定“@1”类型并将其注册为 bean。您可以逐个类启用配置属性,或启用与组件扫描工作方式类似的配置属性扫描。
Spring Boot provides infrastructure to bind @ConfigurationProperties
types and register them as beans.
You can either enable configuration properties on a class-by-class basis or enable configuration property scanning that works in a similar manner to component scanning.
有时,使用“@2”进行注释的类可能不适合扫描,例如,如果您正在开发自己的自动配置,或您希望有条件地启用它们。在这些情况下,请使用“@3”注释指定要使用该类型的列表。这可以在任何“@4”类上完成,如下例所示:
Sometimes, classes annotated with @ConfigurationProperties
might not be suitable for scanning, for example, if you’re developing your own auto-configuration or you want to enable them conditionally.
In these cases, specify the list of types to process using the @EnableConfigurationProperties
annotation.
This can be done on any @Configuration
class, as shown in the following example:
要使用配置属性扫描,请向您的应用程序添加“@5”注释。通常,它被添加到使用“@6”进行注释的主应用程序类,但它可以被添加到任何“@7”类。默认情况下,将从声明注释的类的包中进行扫描。如果您希望定义要扫描的特定包,可以按照如下示例进行操作:
To use configuration property scanning, add the @ConfigurationPropertiesScan
annotation to your application.
Typically, it is added to the main application class that is annotated with @SpringBootApplication
but it can be added to any @Configuration
class.
By default, scanning will occur from the package of the class that declares the annotation.
If you want to define specific packages to scan, you can do so as shown in the following example:
当“@8”bean 使用配置属性扫描或通过“@9”注册时,bean 具有常规名称:“@10”,其中“@11”是在“@12”注释中指定的环境密钥前缀,“@13”是 bean 的完全限定名称。如果注释未提供任何前缀,则只使用 bean 的完全限定名称。 When the 假设它在“@14”包中,则上面“@15”示例的 bean 名称为“@16”。 Assuming that it is in the |
我们建议“@26”只处理环境,尤其是,不从上下文中注入其他 bean。对于特殊情况,可以使用 setter 注入或该框架提供的任何“@27”接口(例如,如果您需要访问“@29”,则可以使用“@28”)。如果您仍然希望使用构造函数注入其他 bean,则配置属性 bean 必须使用“@30”进行注释,并使用基于 JavaBean 的属性绑定。
We recommend that @ConfigurationProperties
only deal with the environment and, in particular, does not inject other beans from the context.
For corner cases, setter injection can be used or any of the *Aware
interfaces provided by the framework (such as EnvironmentAware
if you need access to the Environment
).
If you still want to inject other beans using the constructor, the configuration properties bean must be annotated with @Component
and use JavaBean-based property binding.
Using @ConfigurationProperties-annotated Types
这种配置方式特别适合于“@31”外部 YAML 配置,如下例所示:
This style of configuration works particularly well with the SpringApplication
external YAML configuration, as shown in the following example:
my:
service:
remote-address: 192.168.1.1
security:
username: "admin"
roles:
- "USER"
- "ADMIN"
要使用“@32”bean,您可以像注入其他任何 bean 一样注入它们,如下例所示:
To work with @ConfigurationProperties
beans, you can inject them in the same way as any other bean, as shown in the following example:
使用“@33”还允许您生成元数据文件,IDE 可使用这些文件为您的专属密钥提供自动完成功能。有关详细信息,请参见“@34”。 |
Using |
Third-party Configuration
除了使用“@35”对类进行注释外,您还可以在公有的“@36”方法上使用它。当您希望将属性绑定到不受您控制的第三方组件时,这样做特别有用。
As well as using @ConfigurationProperties
to annotate a class, you can also use it on public @Bean
methods.
Doing so can be particularly useful when you want to bind properties to third-party components that are outside of your control.
要从“@37”属性配置 bean,请将其“@38”添加到其 bean 注册,如下例所示:
To configure a bean from the Environment
properties, add @ConfigurationProperties
to its bean registration, as shown in the following example:
任何使用“@39”前缀定义的 JavaBean 属性都以类似于前面“@41”示例的方式映射到该“@40”bean。
Any JavaBean property defined with the another
prefix is mapped onto that AnotherComponent
bean in manner similar to the preceding SomeProperties
example.
Relaxed Binding
Spring Boot 使用一些宽松的规则将“@42”属性绑定到“@43”bean,因此“@44”属性名称和 bean 属性名称之间不必完全匹配。这方面有用的常见示例包括以破折号分隔的环境属性(例如,“@45”绑定到“@46”)和首字母大写的环境属性(例如,“@47”绑定到“@48”)。
Spring Boot uses some relaxed rules for binding Environment
properties to @ConfigurationProperties
beans, so there does not need to be an exact match between the Environment
property name and the bean property name.
Common examples where this is useful include dash-separated environment properties (for example, context-path
binds to contextPath
), and capitalized environment properties (for example, PORT
binds to port
).
例如,考虑以下“@49”类:
As an example, consider the following @ConfigurationProperties
class:
使用前面代码,可以使用以下所有属性名称:
With the preceding code, the following properties names can all be used:
Property | Note |
---|---|
|
Kebab case, which is recommended for use in |
|
Standard camel case syntax. |
|
Underscore notation, which is an alternative format for use in |
|
Upper case format, which is recommended when using system environment variables. |
注释 must 的 |
The |
Property Source | Simple | List |
---|---|---|
Properties Files |
Camel case, kebab case, or underscore notation |
Standard list syntax using |
YAML Files |
Camel case, kebab case, or underscore notation |
Standard YAML list syntax or comma-separated values |
Environment Variables |
Upper case format with underscore as the delimiter (see Binding From Environment Variables). |
Numeric values surrounded by underscores (see Binding From Environment Variables) |
System properties |
Camel case, kebab case, or underscore notation |
Standard list syntax using |
当可能时,我们建议按照小写的连字符形式存储属性,例如 |
We recommend that, when possible, properties are stored in lower-case kebab format, such as |
Binding Maps
绑定到 Map
属性时,您可能需要使用特殊的花括号形式以便保留原始 key
值。如果密钥没有被 []
所包围,则将移除任何非字母数字、-
或 .
的字符。
When binding to Map
properties you may need to use a special bracket notation so that the original key
value is preserved.
If the key is not surrounded by []
, any characters that are not alpha-numeric, -
or .
are removed.
例如,考虑绑定下面的属性到一个 Map<String,String>
:
For example, consider binding the following properties to a Map<String,String>
:
my: map: "[/key1]": "value1" "[/key2]": "value2" "/key3": "value3"
对于 YAML 文件,为了正确解析密钥,花括号需要被引号包围。 |
For YAML files, the brackets need to be surrounded by quotes for the keys to be parsed properly. |
上面的属性将绑定到一个 Map
,其密钥为映射中的 /key1
、/key2
和 key3
。已从 key3
中删除斜杠,因为它没有被方括号包围。
The properties above will bind to a Map
with /key1
, /key2
and key3
as the keys in the map.
The slash has been removed from key3
because it was not surrounded by square brackets.
绑定到标量值时,其中包含 .
的密钥不需要被 []
所包围。标量值包括枚举值以及 java.lang
包中的所有类型(Object
除外)。将 a.b=c
绑定到 Map<String, String>
将保留密钥中的 .
,并返回一个包含条目 {"a.b"="c"}
的映射。对于任何其他类型,如果您的 key
包含一个 .
,则您需要使用花括号形式。例如,将 a.b=c
绑定到 Map<String, Object>
将返回一个包含条目 {"a"={"b"="c"}}
的映射,而 [a.b]=c
将返回一个包含条目 {"a.b"="c"}
的映射。
When binding to scalar values, keys with .
in them do not need to be surrounded by []
.
Scalar values include enums and all types in the java.lang
package except for Object
.
Binding a.b=c
to Map<String, String>
will preserve the .
in the key and return a Map with the entry {"a.b"="c"}
.
For any other types you need to use the bracket notation if your key
contains a .
.
For example, binding a.b=c
to Map<String, Object>
will return a Map with the entry {"a"={"b"="c"}}
whereas [a.b]=c
will return a Map with the entry {"a.b"="c"}
.
Binding From Environment Variables
大多数操作系统都针对可用于环境变量的名称制定了严格的规则。例如,Linux shell 变量只能包含字母(a
到 z
或 A
到 Z
)、数字(0
到 9
)或下划线字符 (_
)。根据惯例,Unix shell 变量的名称还会采用大写。
Most operating systems impose strict rules around the names that can be used for environment variables.
For example, Linux shell variables can contain only letters (a
to z
or A
to Z
), numbers (0
to 9
) or the underscore character (_
).
By convention, Unix shell variables will also have their names in UPPERCASE.
Spring Boot 的宽松绑定规则最大限度地设计为与这些命名限制兼容。
Spring Boot’s relaxed binding rules are, as much as possible, designed to be compatible with these naming restrictions.
要将规范形式中的属性名称转换为环境变量名称,您可以遵循这些规则:
To convert a property name in the canonical-form to an environment variable name you can follow these rules:
-
Replace dots (
.
) with underscores (_
). -
Remove any dashes (
-
). -
Convert to uppercase.
例如,配置属性 spring.main.log-startup-info
将是一个名为 SPRING_MAIN_LOGSTARTUPINFO
的环境变量。
For example, the configuration property spring.main.log-startup-info
would be an environment variable named SPRING_MAIN_LOGSTARTUPINFO
.
在绑定到对象列表时也可以使用环境变量。要绑定到 List
,应使用下划线在变量名称中包围元素编号。
Environment variables can also be used when binding to object lists.
To bind to a List
, the element number should be surrounded with underscores in the variable name.
例如,配置属性 my.service[0].other
将使用名为 MY_SERVICE_0_OTHER
的环境变量。
For example, the configuration property my.service[0].other
would use an environment variable named MY_SERVICE_0_OTHER
.
Caching
宽松绑定使用缓存来提高性能。默认情况下,此缓存仅应用于不可变属性源。例如,要自定义此行为,例如启用可变属性源的缓存,请使用 ConfigurationPropertyCaching
。
Relaxed binding uses a cache to improve performance. By default, this caching is only applied to immutable property sources.
To customize this behavior, for example to enable caching for mutable property sources, use ConfigurationPropertyCaching
.
Merging Complex Types
当列表在多个地方配置时,覆盖通过替换整个列表起作用。
When lists are configured in more than one place, overriding works by replacing the entire list.
例如,假设一个 s12 对象具有 s13 和 s14 属性,它们在默认为 s15 的情况下更新。以下示例从 s17 揭示了 s16 对象的列表:
For example, assume a MyPojo
object with name
and description
attributes that are null
by default.
The following example exposes a list of MyPojo
objects from MyProperties
:
考虑以下配置:
Consider the following configuration:
my: list: - name: "my name" description: "my description" --- spring: config: activate: on-profile: "dev" my: list: - name: "my another name"
如果 dev
配置文件未激活,则 MyProperties.list
包含一个 MyPojo
条目,如前所定义。但是,如果 dev
配置文件已启用,则 list
still 仅包含一个条目(名称为 my another name
,描述为 null
)。此配置 does not 会将第二个 MyPojo
实例添加到列表,但不会合并项目。
If the dev
profile is not active, MyProperties.list
contains one MyPojo
entry, as previously defined.
If the dev
profile is enabled, however, the list
still contains only one entry (with a name of my another name
and a description of null
).
This configuration does not add a second MyPojo
instance to the list, and it does not merge the items.
当在多个配置文件中指定 List
时,会使用优先级最高的那个(并且仅使用该那个)。考虑以下示例:
When a List
is specified in multiple profiles, the one with the highest priority (and only that one) is used.
Consider the following example:
my: list: - name: "my name" description: "my description" - name: "another name" description: "another description" --- spring: config: activate: on-profile: "dev" my: list: - name: "my another name"
在上述示例中,如果 dev
配置文件处于活动状态,则 MyProperties.list
包含 one MyPojo
条目(名称为 my another name
,描述为 null
)。对于 YAML,可以用逗号分隔的列表和 YAML 列表来完全覆盖列表的内容。
In the preceding example, if the dev
profile is active, MyProperties.list
contains one MyPojo
entry (with a name of my another name
and a description of null
).
For YAML, both comma-separated lists and YAML lists can be used for completely overriding the contents of the list.
对于 Map
属性,您可以与从多个来源获取的属性值绑定。但是,对于多个来源中的同一属性,将使用优先级最高的那个。以下示例从 MyProperties
公开 Map<String, MyPojo>
:
For Map
properties, you can bind with property values drawn from multiple sources.
However, for the same property in multiple sources, the one with the highest priority is used.
The following example exposes a Map<String, MyPojo>
from MyProperties
:
考虑以下配置:
Consider the following configuration:
my: map: key1: name: "my name 1" description: "my description 1" --- spring: config: activate: on-profile: "dev" my: map: key1: name: "dev name 1" key2: name: "dev name 2" description: "dev description 2"
如果 dev
配置文件未激活,则 MyProperties.map
包含一个键为 key1
的条目(名称为 my name 1
,描述为 my description 1
)。但是,如果 dev
配置文件已启用,则 map
包含两个键为 key1
(名称为 dev name 1
,描述为 my description 1
)和 key2
(名称为 dev name 2
,描述为 dev description 2
)的条目。
If the dev
profile is not active, MyProperties.map
contains one entry with key key1
(with a name of my name 1
and a description of my description 1
).
If the dev
profile is enabled, however, map
contains two entries with keys key1
(with a name of dev name 1
and a description of my description 1
) and key2
(with a name of dev name 2
and a description of dev description 2
).
上述合并规则应用于所有属性来源的属性,而不仅仅是文件。 |
The preceding merging rules apply to properties from all property sources, and not just files. |
Properties Conversion
Spring Boot 尝试在绑定到 @ConfigurationProperties
Bean 时强制将外部应用程序属性转换为正确的类型。如果您需要自定义类型转换,可以提供一个 ConversionService
Bean(Bean 名称 conversionService
)或自定义属性编辑器(通过 CustomEditorConfigurer
Bean)或自定义 Converters
(带标注为 @ConfigurationPropertiesBinding
的 Bean 定义)。
Spring Boot attempts to coerce the external application properties to the right type when it binds to the @ConfigurationProperties
beans.
If you need custom type conversion, you can provide a ConversionService
bean (with a bean named conversionService
) or custom property editors (through a CustomEditorConfigurer
bean) or custom Converters
(with bean definitions annotated as @ConfigurationPropertiesBinding
).
由于该 Bean 在应用程序生命周期的非常早阶段被请求,因此请确保限制 |
As this bean is requested very early during the application lifecycle, make sure to limit the dependencies that your |
Converting Durations
Spring Boot 专用于表达持续时间。如果您公开 java.time.Duration
属性,则应用程序属性中提供以下格式:
Spring Boot has dedicated support for expressing durations.
If you expose a java.time.Duration
property, the following formats in application properties are available:
-
A regular
long
representation (using milliseconds as the default unit unless a@DurationUnit
has been specified) -
The standard ISO-8601 format {apiref-openjdk}/java.base/java/time/Duration.html#parse(java.lang.CharSequence)[used by
java.time.Duration
] -
A more readable format where the value and the unit are coupled (
10s
means 10 seconds)
请考虑以下示例:
Consider the following example:
要指定 30 秒的会话超时,30
、PT30S`和 `30s`都是等效的。以下任一形式都可以指定 500 毫秒的读取超时:`500
、PT0.5S`和 `500ms
。
To specify a session timeout of 30 seconds, 30
, PT30S
and 30s
are all equivalent.
A read timeout of 500ms can be specified in any of the following form: 500
, PT0.5S
and 500ms
.
您还可以使用任何受支持的单位。它们是:
You can also use any of the supported units. These are:
-
ns
for nanoseconds -
us
for microseconds -
ms
for milliseconds -
s
for seconds -
m
for minutes -
h
for hours -
d
for days
默认单位是毫秒,可以使用 `@DurationUnit`覆盖,如上例所示。
The default unit is milliseconds and can be overridden using @DurationUnit
as illustrated in the sample above.
如果您更喜欢使用构造函数绑定,可以使用相同的属性,如下例所示:
If you prefer to use constructor binding, the same properties can be exposed, as shown in the following example:
如果您正在升级一个 |
If you are upgrading a |
Converting Periods
除了持续时间之外,Spring Boot 还可以使用 `java.time.Period`类型。以下格式可用于应用程序属性:
In addition to durations, Spring Boot can also work with java.time.Period
type.
The following formats can be used in application properties:
-
An regular
int
representation (using days as the default unit unless a@PeriodUnit
has been specified) -
The standard ISO-8601 format {apiref-openjdk}/java.base/java/time/Period.html#parse(java.lang.CharSequence)[used by
java.time.Period
] -
A simpler format where the value and the unit pairs are coupled (
1y3d
means 1 year and 3 days)
简单格式支持以下单位:
The following units are supported with the simple format:
-
y
for years -
m
for months -
w
for weeks -
d
for days
`java.time.Period`类型实际上从未存储周数,它是一个表示 "`7 days`"的快捷方式。 |
The |
Converting Data Sizes
Spring Framework 有一个 `DataSize`值类型,表示以字节为单位的大小。如果您公开了一个 `DataSize`属性,应用程序属性中提供了以下格式:
Spring Framework has a DataSize
value type that expresses a size in bytes.
If you expose a DataSize
property, the following formats in application properties are available:
-
A regular
long
representation (using bytes as the default unit unless a@DataSizeUnit
has been specified) -
A more readable format where the value and the unit are coupled (
10MB
means 10 megabytes)
请考虑以下示例:
Consider the following example:
要指定 10 兆字节的缓冲区大小,10`和 `10MB`是等效的。可以将大小阈值指定为 256 字节,如下所示:`256`或 `256B
。
To specify a buffer size of 10 megabytes, 10
and 10MB
are equivalent.
A size threshold of 256 bytes can be specified as 256
or 256B
.
您还可以使用任何受支持的单位。它们是:
You can also use any of the supported units. These are:
-
B
for bytes -
KB
for kilobytes -
MB
for megabytes -
GB
for gigabytes -
TB
for terabytes
默认单位是字节,可以使用 `@DataSizeUnit`覆盖,如上例所示。
The default unit is bytes and can be overridden using @DataSizeUnit
as illustrated in the sample above.
如果您更喜欢使用构造函数绑定,可以使用相同的属性,如下例所示:
If you prefer to use constructor binding, the same properties can be exposed, as shown in the following example:
升级 |
If you are upgrading a |
@ConfigurationProperties Validation
Spring Boot 会尝试验证 @ConfigurationProperties
类,只要它们使用 Spring 的 @Validated
注解进行注释。您可以在配置类上直接使用 JSR-303 jakarta.validation
约束注解。为此,请确保您的类路径中存在兼容的 JSR-303 实现,然后将约束注解添加到字段中,如下例所示:
Spring Boot attempts to validate @ConfigurationProperties
classes whenever they are annotated with Spring’s @Validated
annotation.
You can use JSR-303 jakarta.validation
constraint annotations directly on your configuration class.
To do so, ensure that a compliant JSR-303 implementation is on your classpath and then add constraint annotations to your fields, as shown in the following example:
您还可以通过使用 |
You can also trigger validation by annotating the |
为了确保即使未找到属性也始终触发嵌套属性的验证,关联的字段必须使用 @Valid`进行注释。以下示例基于前面的 `MyProperties
示例:
To ensure that validation is always triggered for nested properties, even when no properties are found, the associated field must be annotated with @Valid
.
The following example builds on the preceding MyProperties
example:
您还可以通过创建名为 configurationPropertiesValidator
的 Bean 定义来添加自定义 Spring Validator
。应该将 @Bean
方法声明为 static
。配置属性验证器在应用程序生命周期的早期创建,并将 @Bean
方法声明为静态允许在无需实例化 @Configuration
类的情况下创建 Bean。这样做避免了可能由早期实例化引起的任何问题。
You can also add a custom Spring Validator
by creating a bean definition called configurationPropertiesValidator
.
The @Bean
method should be declared static
.
The configuration properties validator is created very early in the application’s lifecycle, and declaring the @Bean
method as static lets the bean be created without having to instantiate the @Configuration
class.
Doing so avoids any problems that may be caused by early instantiation.
|
The |
@ConfigurationProperties vs. @Value
@Value
注解是一个核心容器特性,它不提供与类型安全配置属性相同的功能。下表总结了 @ConfigurationProperties
和 @Value
支持的功能:
The @Value
annotation is a core container feature, and it does not provide the same features as type-safe configuration properties.
The following table summarizes the features that are supported by @ConfigurationProperties
and @Value
:
Feature | @ConfigurationProperties |
@Value |
---|---|---|
Yes |
Limited (see note below) |
|
Yes |
No |
|
|
No |
Yes |
如果您确实想要使用 If you do want to use 例如, For example, |
如果您为自己的组件定义了一组配置键,我们建议您将它们分组到使用 @ConfigurationProperties
进行注释的 POJO 中。这样做将为您提供结构化的类型安全对象,您可以将其注入到您自己的 Bean 中。
If you define a set of configuration keys for your own components, we recommend you group them in a POJO annotated with @ConfigurationProperties
.
Doing so will provide you with structured, type-safe object that you can inject into your own beans.
application property files 中的 SpEL
表达式在解析这些文件并填充环境时不会被处理。但是,可以在 @Value
中编写 SpEL
表达式。如果来自应用程序属性文件的属性值是 SpEL
表达式,则在通过 @Value
使用它时对其进行评估。
SpEL
expressions from application property files are not processed at time of parsing these files and populating the environment.
However, it is possible to write a SpEL
expression in @Value
.
If the value of a property from an application property file is a SpEL
expression, it will be evaluated when consumed through @Value
.