Spring Boot 2.0.0参考手册_中英文对照_Part IV_24

文章作者:Tyan
博客:noahsnail.com  |  CSDN  |  简书

24. Externalized Configuration

Spring Boot allows you to externalize your configuration so you can work with the same application code in different environments. You can use properties files, YAML files, environment variables and command-line arguments to externalize configuration. Property values can be injected directly into your beans using the @Value annotation, accessed via Spring’s Environment abstraction or bound to structured objects via @ConfigurationProperties.

Spring Boot允许你进行外部化配置,因此可以将同样的应用代码在不同的环境中运行。你可以使用属性文件,YAML文件,环境变量和命令行参数来进行外部化配置。属性值可以使用@Value注解直接注入到你的beans中,通过Spring的Environment抽象或通过@ConfigurationProperties绑定到结构化对象上来访问。

Spring Boot uses a very particular PropertySource order that is designed to allow sensible overriding of values. Properties are considered in the following order:

Spring Boot使用非常特别的PropertySource顺序,这个顺序的设计是为了允许值的合理重写。属性被认为是按照以下顺序:

  1. Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
  2. @TestPropertySource annotations on your tests.
  3. @SpringBootTest#properties annotation attribute on your tests.
  4. Command line arguments.
  5. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
  6. ServletConfig init parameters.
  7. ServletContext init parameters.
  8. JNDI attributes from java:comp/env.
  9. Java System properties (System.getProperties()).
  10. OS environment variables.
  11. A RandomValuePropertySource that only has properties in random.*.
  12. Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
  13. Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
  14. Application properties outside of your packaged jar (application.properties and YAML variants).
  15. Application properties packaged inside your jar (application.properties and YAML variants).
  16. @PropertySource annotations on your @Configuration classes.
  17. Default properties (specified using SpringApplication.setDefaultProperties).

  18. 根目录下的开发工具全局设置属性(当开发工具激活时为~/.spring-boot-devtools.properties)。

  19. 测试中的@TestPropertySource注解。
  20. 测试中的@SpringBootTest#properties注解特性。
  21. 命令行参数。
  22. SPRING_APPLICATION_JSON中的属性(环境变量或系统属性中的内联JSON嵌入)。
  23. ServletConfig初始化参数。
  24. ServletContext初始化参数。
  25. java:comp/env的JNDI特性。
  26. Java系统属性 (System.getProperties())。
  27. 操作系统环境变量。
  28. RandomValuePropertySource只在random.*中有属性。
  29. jar包之外的指定配置文件的应用属性(application-{profile}.properties和YAML变量)。
  30. jar包之内的指定配置文件的应用属性(application-{profile}.properties和YAML变量)。
  31. jar包之外的应用属性 (application.properties和YAML变量)。
  32. jar包之内的应用属性 (application.properties和YAML变量)。
  33. @Configuration类中的@PropertySource注解 。
  34. 默认属性(通过SpringApplication.setDefaultProperties指定).

To provide a concrete example, suppose you develop a @Component that uses a name property:

为了提供一个具体的例子,假设你开发了一个使用name属性的@Component

1
2
3
4
5
6
7
8
9
10
11
12
import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*

@Component
public class MyBean {

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

// ...

}

On your application classpath (e.g. inside your jar) you can have an application.properties that provides a sensible default property value for name. When running in a new environment, an application.properties can be provided outside of your jar that overrides the name; and for one-off testing, you can launch with a specific command line switch (e.g. java -jar app.jar --name="Spring").

在你的应用路径中(例如在你的jar内部),你可以使用application.propertiesname提供一个合理的默认属性值。当在新环境运行时,application.properties可以在jar外部提供来重写name;对于一次性测试,你可以通过指定的命令行切换来启动(例如java -jar app.jar --name="Spring")。

The SPRING_APPLICATION_JSON properties can be supplied on the command line with an environment variable. For example in a UN*X shell:

1
$ SPRING_APPLICATION_JSON='{"foo":{"bar":"spam"}}' java -jar myapp.jar

In this example you will end up with foo.bar=spam in the Spring Environment. You can also supply the JSON as spring.application.json in a System variable:

1
$ java -Dspring.application.json='{"foo":"bar"}' -jar myapp.jar

or command line argument:

1
$ java -jar myapp.jar --spring.application.json='{"foo":"bar"}'

or as a JNDI variable java:comp/env/spring.application.json.

 

SPRING_APPLICATION_JSON可以在命令行中通过环境变量提供。例如在UNIX shell中:

1
$ SPRING_APPLICATION_JSON='{"foo":{"bar":"spam"}}' java -jar myapp.jar

在这个例子中,Spring的Environment中会有foo.bar=spam。你也可以在系统变量中提供JSON作为spring.application.json

1
$ java -Dspring.application.json='{"foo":"bar"}' -jar myapp.jar

或命令行参数:

1
$ java -jar myapp.jar --spring.application.json='{"foo":"bar"}'

或JNDI变量java:comp/env/spring.application.json

24.1 Configuring random values

The RandomValuePropertySource is useful for injecting random values (e.g. into secrets or test cases). It can produce integers, longs, uuids or strings, e.g.

当注入随机值时,RandomValuePropertySource是很有用的(例如,注入秘密或测试用例)。它可以产生integerslongsuuidsstrings,例如:

1
2
3
4
5
6
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]}

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 (exclusive).

random.int*语法OPEN value (,max) CLOSEOPEN,CLOSE可以是任何字符,value,max是整数。如果提供了max,则value是最小值,max是最大值(不包含)。

24.2 Accessing command line properties

By default SpringApplication will convert any command line option arguments (starting with ‘–’, e.g. --server.port=9000) to a property and add it to the Spring Environment. As mentioned above, command line properties always take precedence over other property sources.

默认情况下,SpringApplication会将任何命令行参数(以--开头,例如--server.port=9000)转换成property并将其添加到Spring的Environment中。正如前面提到的那样,命令行属性总是优先于其它的配置源。

If you don’t want command line properties to be added to the Environment you can disable them using SpringApplication.setAddCommandLineProperties(false).

如果你想命令行属性添加到Environment中,你可以使用SpringApplication.setAddCommandLineProperties(false)禁用它。

24.3 Application property files

SpringApplication will load properties from application.properties files in the following locations and add them to the Spring Environment:

  1. A /config subdirectory of the current directory.
  2. The current directory
  3. A classpath /config package
  4. The classpath root

SpringApplication会从以下位置的application.properties文件中加载属性并将它们添加到Spring的Environment中:

  1. 当前目录的子目录/config

  2. 当前目录

  3. classpath中的/config

  4. classpath的根目录

The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).

这个列表是按优先级排序的(在更高位置的属性会重写定义在更低位置的属性)。

You can also use YAML (‘.yml’) files as an alternative to ‘.properties’.

 

你也可以使用YAML(.yml)文件来代替.properties文件。

If you don’t like application.properties as the configuration file name you can switch to another by specifying a spring.config.name environment property. You can also refer to an explicit location using the spring.config.location environment property (comma-separated list of directory locations, or file paths).

如果你不喜欢用application.properties作为配置文件的名字,你可以通过指定spring.config.name环境属性来来改变配置文件的名字。你也可以使用spring.config.location环境属性来引用一个显式的位置(目录位置或文件路径以逗号分隔)。

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

or

1
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

spring.config.name and spring.config.location are used very early to determine which files have to be loaded so they have to be defined as an environment property (typically OS env, system property or command line argument).

 

spring.config.namespring.config.location可以在早期用来决定加载哪一个文件,因此必须被定义为环境属性(通常是操作系统环境,系统属性或命令行参数)。

If spring.config.location contains directories (as opposed to files) they should end in / (and will be appended with the names generated from spring.config.name before being loaded, including profile-specific file names). Files specified in spring.config.location are used as-is, with no support for profile-specific variants, and will be overridden by any profile-specific properties.

如果spring.config.location包含目录(相对于文件而言),它们应该以/结尾(在加载之前,在后面添加上从spring.config.name中产生的名字,包括指定配置文件的名字)。在spring.config.location中指定的文件按原样使用,不支持指定配置文件变量,将会被任何指定配置文件的属性覆盖。

The default search path classpath:,classpath:/config,file:,file:config/ is always used, irrespective of the value of spring.config.location. This search path is ordered from lowest to highest precedence (file:config/ wins). If you do specify your own locations, they take precedence over all of the default locations and use the same lowest to highest precedence ordering. In that way you can set up default values for your application in application.properties (or whatever other basename you choose with spring.config.name) and override it at runtime with a different file, keeping the defaults.

默认搜索路径一直用classpath:,classpath:/config,file:,file:config/,不管spring.config.location中的值。搜索路径按从低到高排序(file:config/最高)。如果你指定了自己的位置,它们优先于所有的默认位置并使用同样的从低到高的顺序。这样你可以在application.properties中为你的应用设置默认值(或你可以选择spring.config.name的其它生成文件基本名),在运行时用其它的文件覆盖它,同时保留默认值。

If you use environment variables rather than system properties, most operating systems disallow period-separated key names, but you can use underscores instead (e.g. SPRING_CONFIG_NAME instead of spring.config.name).

 

如果你使用环境变量而不是系统属性,大多数操作系统不允许句号分隔的关键字,但你可以用下划线代替(例如,SPRING_CONFIG_NAME代替spring.config.name)。

If you are running in a container then JNDI properties (in java:comp/env) or servlet context initialization parameters can be used instead of, or as well as, environment variables or system properties.

 

如果你在容器中运行,那么JNDI属性(在java:comp/env中)或servlet上下文初始化参数也可以用来代替环境变量或系统属性。

24.4 Profile-specific properties

In addition to application.properties files, profile-specific properties can also be defined using the naming convention application-{profile}.properties. The Environment has a set of default profiles (by default [default]) which are used if no active profiles are set (i.e. if no profiles are explicitly activated then properties from application-default.properties are loaded).

除了application.properties文件之外,特定的profile属性也可以使用命名规范application-{profile}.properties来定义。Environment有一系列默认配置文件(默认为[default]),如果没有设置激活的配置文件,会使用默认的配置文件(例如,如果没有激活显式的配置文件,则会加载application-default.properties中的属性)。

Profile-specific properties are loaded from the same locations as standard application.properties, with profile-specific files always overriding the non-specific ones irrespective of whether the profile-specific files are inside or outside your packaged jar.

特定的profile属性会从相同位置加载application.properties,特定的profile文件总是覆盖非特定的配置文件,无论特定profile文件在你打包的jar内部还是外部。

If several profiles are specified, a last wins strategy applies. For example, profiles specified by the spring.profiles.active property are added after those configured via the SpringApplication API and therefore take precedence.

如果指定了几个配置文件,将会应用最后一个。例如,spring.profiles.active属性指定的配置文件在那些配置的文件之后通过SpringApplication API添加,因此优先级更高。

If you have specified any files in spring.config.location, profile-specific variants of those files will not be considered. Use directories in spring.config.location if you also want to also use profile-specific properties.

 

如果你在spring.config.location中指定了任何文件,那些文件的特定profile版本将不会被考虑。如果你也想使用特定的profile属性,在spring.config.location中使用目录。

24.5 Placeholders in properties

The values in application.properties are filtered through the existing Environment when they are used so you can refer back to previously defined values (e.g. from System properties).

当使用application.properties中的值时,会通过现有的Environment进行过滤,因此你可以参考前面定义的值(例如从系统属性中)。

1
2
app.name=MyApp
app.description=${app.name} is a Spring Boot application

You can also use this technique to create ‘short’ variants of existing Spring Boot properties. See the Section 70.4, “Use ‘short’ command line arguments” how-to for details.

 

你也可以使用这个技术来创建现有的Spring Boot属性的short版本。怎样使用的更多细节请看70.4小节,“Use ‘short’ command line arguments”。

24.6 Using YAML instead of Properties

YAML is a superset of JSON, and as such is a very convenient format for specifying hierarchical configuration data. The SpringApplication class will automatically support YAML as an alternative to properties whenever you have the SnakeYAML library on your classpath.

YAML是JSON的超集,它可以用一种非常方便的形式来指定分层配置数据。当你的类路径有SnakeYAML库时,SpringApplication类自动支持YAML作为properties的一个替代品。

If you use ‘Starters’ SnakeYAML will be automatically provided via spring-boot-starter.

 

如果你使用‘Starters’,SnakeYAML将由spring-boot-starter自动提供。

24.6.1 Loading YAML

Spring Framework provides two convenient classes that can be used to load YAML documents. The YamlPropertiesFactoryBean will load YAML as Properties and the YamlMapFactoryBean will load YAML as a Map.

Spring框架提供了两个类用来方便的加载YAML文档。YamlPropertiesFactoryBean将加载YAML作为PropertiesYamlMapFactoryBean将加载YAML作为Map

For example, the following YAML document:

例如,下面的YAML文档:

1
2
3
4
5
6
7
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App

Would be transformed into these properties:

将被转换成这些属性:

1
2
3
4
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App

YAML lists are represented as property keys with [index] dereferencers, for example this YAML:

YAML列表通过[index]解引用表示为属性的key,例如这个YAML:

1
2
3
4
my:
servers:
- dev.bar.com
- foo.bar.com

Would be transformed into these properties:

将被转换成这些属性:

1
2
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com

To bind to properties like that using the Spring DataBinder utilities (which is what @ConfigurationProperties does) you need to have a property in the target bean of type java.util.List (or Set) and you either need to provide a setter, or initialize it with a mutable value, e.g. this will bind to the properties above:

为了像使用Spring的DataBinder一样(@ConfigurationProperties的功能)绑定这些属性,你需要在类型为java.util.List(或Set)的目标bean中有属性,你需要提供一个setter或用一个可变的值来对它初始化,例如,绑定上面的属性值:

1
2
3
4
5
6
7
8
9
@ConfigurationProperties(prefix="my")
public class Config {

private List<String> servers = new ArrayList<String>();

public List<String> getServers() {
return this.servers;
}
}

24.6.2 Exposing YAML as properties in the Spring Environment

The YamlPropertySourceLoader class can be used to expose YAML as a PropertySource in the Spring Environment. This allows you to use the familiar @Value annotation with placeholders syntax to access YAML properties.

YamlPropertySourceLoader类可以在Spring的Environment中将YAML作为PropertySource。这允许你使用熟悉的@Value注解和占位符语法来访问YAML属性。

24.6.3 Multi-profile YAML documents

You can specify multiple profile-specific YAML documents in a single file by using a spring.profiles key to indicate when the document applies. For example:

你可以在单个文件中指定多个特定profile的YAML文档,当应用文档时,通过spring.profiles关键字来表明使用哪个文档。例如:

1
2
3
4
5
6
7
8
9
10
11
12
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production
server:
address: 192.168.1.120

In the example above, the server.address property will be 127.0.0.1 if the development profile is active. If the development and productionprofiles are not enabled, then the value for the property will be 192.168.1.100.

在上面的例子中,如果development profile被激活,server.address的值为127.0.0.1。如果developmentproduction profile不可用,server.address的值为192.168.1.100

The default profiles are activated if none are explicitly active when the application context starts. So in this YAML we set a value for security.user.password that is only available in the “default” profile:

当应用上下文启动时,如果没有显式的激活profile,则激活默认的profile。因此在这个YAML文件中我们仅在”default” profile中设置了security.user.password

1
2
3
4
5
6
7
8
server:
port: 8000
---
spring:
profiles: default
security:
user:
password: weak

whereas in this example, the password is always set because it isn’t attached to any profile, and it would have to be explicitly reset in all other profiles as necessary:

在这个例子中,密码总是设置的,因为它没有添加到如何profile中,必要时我们必须在其它的profile中显式的对它重新设置:

1
2
3
4
5
server:
port: 8000
security:
user:
password: weak

Spring profiles designated using the “spring.profiles” element may optionally be negated using the ! character. If both negated and non-negated profiles are specified for a single document, at least one non-negated profile must match and no negated profiles may match.

Spring profiles被设计为使用”spring.profiles”元素可以选择性的用!字符进行否定。如果否定的和非否定的profile指向一个单独的文档,必须至少匹配一个非否定的profile,可能没有否定的profile进行匹配。

24.6.4 YAML shortcomings

YAML files can’t be loaded via the @PropertySource annotation. So in the case that you need to load values that way, you need to use a properties file.

YAML文件不能通过@PropertySource注解进行加载。因此在这种情况下如果你需要加载值,你需要使用属性文件。

24.6.5 Merging YAML lists

As we have seen above, any YAML content is ultimately transformed to properties. That process may be counter intuitive when overriding “list” properties via a profile.

正如我们上面看到的,任何YAML内容最终都要转换成属性。当通过profile重写“list“属性时,这个过程可能有违直觉。

For example, assume a MyPojo object with name and description attributes that are null by default. Let’s expose a list of MyPojo from FooProperties:

例如,假设MyPojo对象的namedescription属性默认情况下为空。从FooProperties公开一个MyPojo列表:

1
2
3
4
5
6
7
8
9
10
@ConfigurationProperties("foo")
public class FooProperties {

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

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

}

Consider the following configuration:

考虑下面的配置:

1
2
3
4
5
6
7
8
9
10
foo:
list:
- name: my name
description: my description
---
spring:
profiles: dev
foo:
list:
- name: my another name

If the dev profile isn’t active, FooProperties.list will contain one MyPojo entry as defined above. If the dev profile is enabled however, the list will still only contain one entry (with name “my another name” and description null). This configuration will not add a second MyPojo instance to the list, and it won’t merge the items.

如果dev profile没有激活,FooProperties.list将包含一个上面定义的MyPojo输入。然而如果dev profile可用,lists仍只包含一个输入(name为“my another name”,description为空)。这个配置将不能添加第二个MyPojolist中,并且它将不能合并这些项。

When a collection is specified in multiple profiles, the one with highest priority is used (and only that one):

当在多个profiles中指定一个集合时,将会使用最高优先级的那个集合(唯一的哪个):

1
2
3
4
5
6
7
8
9
10
11
12
foo:
list:
- name: my name
description: my description
- name: another name
description: another description
---
spring:
profiles: dev
foo:
list:
- name: my another name

In the example above, considering that the dev profile is active, FooProperties.list will contain one MyPojo entry (with name “my another name” and description null).

在上面的例子中,假设dev profile被激活,FooProperties.list将包含一个MyPojo输入(name为“my another name”,description为空)。

24.7 Type-safe Configuration Properties

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 allows strongly typed beans to govern and validate the configuration of your application. For example:

使用@Value("${property}")注解来注入配置信息有时会很麻烦,尤其是你正在使用多属性或你的数据本质上是分层的情况下。Spring Boot提供了一种处理属性的可替代方法,允许强类型的beans管理和验证你的应用的配置。例如:

1
2
3
4
5
6
7
8
9
10
@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {

private String username;

private InetAddress remoteAddress;

// ... getters and setters

}

The getters and setters are advisable, since binding is via standard Java Beans property descriptors, just like in Spring MVC. They are mandatory for immutable types or those that are directly coercible from String. As long as they are initialized, maps, collections, and arrays need a getter but not necessarily a setter since they can be mutated by the binder. If there is a setter, Maps, collections, and arrays can be created. Maps and collections can be expanded with only a getter, whereas arrays require a setter. Nested POJO properties can also be created (so a setter is not mandatory) if they have a default constructor, or a constructor accepting a single value that can be coerced from String. Some people use Project Lombok to add getters and setters automatically.

 

建议添加getters和setters,绑定是通过标准的Java Beans属性描述符,像在Spring MVC中一样。对于不可变类型或那些从String中可直接强制转换的类型,它们是强制性的。只要它们被初始化,maps,集合或数组需要getter方法,但不需要setter方法因为通过绑定起它们可以直接变化。如果有setter,可以创建Maps,集合和数组。Maps和集合可以通过getter扩展,数组扩展需要setter。如果它们有默认的构造函数,或构造函数接收可以从String类型强制转换的值,嵌入的POJO属性也可以创建(因此setter不是强制性的)。一些人使用Lombok项目来自动添加getter和setter。

See also the differences between @Value and @ConfigurationProperties.

 

请看@Value@ConfigurationProperties之间的不同。

You also need to list the properties classes to register in the @EnableConfigurationProperties annotation:

你也需要在@EnableConfigurationProperties注解中列出要注册的属性类:

1
2
3
4
@Configuration
@EnableConfigurationProperties(ConnectionProperties.class)
public class MyConfiguration {
}

When @ConfigurationProperties bean is registered that way, the bean will have a conventional name: <prefix>-<fqn>, where <prefix> is the environment key prefix specified in the @ConfigurationProperties annotation and <fqn> the fully qualified name of the bean. If the annotation does not provide any prefix, only the fully qualified name of the bean is used.

The bean name in the example above will be connection-com.example.ConnectionProperties, assuming that ConnectionProperties sits in the com.example package.

 

@ConfigurationProperties以那种方式注册时,这个bean将有一个常规的名字:<prefix>-<fqn><prefix>是在@ConfigurationProperties注解中指定的环境关键字的前缀,<fqn>是bean的完整合格的名字。如果注解没有提供任何前缀,则只用bean的完整合格的名字。

在上面的例子中bean名字是connection-com.example.ConnectionProperties,假设ConnectionPropertiescom.example包中。

Even if the configuration above will create a regular bean for ConnectionProperties, we recommend that @ConfigurationProperties only deal with the environment and in particular does not inject other beans from the context. Having said that, The @EnableConfigurationProperties annotation is also automatically applied to your project so that any existing bean annotated with @ConfigurationProperties will be configured from the Environmentproperties. You could shortcut MyConfiguration above by making sure ConnectionProperties is a already a bean:

即使上面的配置会为ConnectionProperties创建一个正规的bean,我们建议@ConfigurationProperties只处理环境,特别是不从上下文中注入其它的beans。已经说过,为了任何带有@ConfigurationProperties注解的bean可以根据Environment属性进行配置,@EnableConfigurationProperties注解也自动应用到你的工程中。确保ConnectionProperties已经是一个bean,你可以简写上面的MyConfiguration

1
2
3
4
5
6
7
@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {

// ... getters and setters

}

This style of configuration works particularly well with the SpringApplication external YAML configuration:

这种风格的配置在SpringApplication的外部化YAML配置中工作的尤其好:

1
2
3
4
5
6
7
# application.yml

connection:
username: admin
remoteAddress: 192.168.1.1

# additional configuration as required

To work with @ConfigurationProperties beans you can just inject them in the same way as any other bean.

为了同@ConfigurationProperties beans一起工作,你可以像任何其它bean一样以相同的方式注入它们:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Service
public class MyService {

private final ConnectionProperties connection;

@Autowired
public MyService(ConnectionProperties connection) {
this.connection = connection;
}

//...

@PostConstruct
public void openConnection() {
Server server = new Server();
this.connection.configure(server);
}

}

Using @ConfigurationProperties also allows you to generate meta-data files that can be used by IDEs. See the Appendix B, Configuration meta-data appendix for details.

 

使用@ConfigurationProperties也允许你生成IDEs可以使用的元数据文件。更多细节请看附录B,配置元数据附录。

24.7.1 Third-party configuration

As well as using @ConfigurationProperties to annotate a class, you can also use it on public @Bean methods. This can be particularly useful when you want to bind properties to third-party components that are outside of your control.

To configure a bean from the Environment properties, add @ConfigurationProperties to its bean registration:

也可以使用@ConfigurationProperties来注解一个类,你也可以在公有的@Bean方法上使用它。当你想绑定属性到你控制之外的第三方组件上时尤其有用。

1
2
3
4
5
@ConfigurationProperties(prefix = "foo")
@Bean
public FooComponent fooComponent() {
...
}

Any property defined with the foo prefix will be mapped onto that FooComponent bean in a similar manner as the ConnectionProperties example above.

任何定义的带有foo前缀的属性都将以类似于上面的ConnectionProperties例子中的方式映射到FooComponent bean中。

24.7.2 Relaxed binding

Spring Boot uses some relaxed rules for binding Environment properties to @ConfigurationProperties beans, so there doesn’t need to be an exact match between the Environment property name and the bean property name. Common examples where this is useful include dashed separated (e.g. context-path binds to contextPath), and capitalized (e.g. PORT binds to port) environment properties.

Spring Boot使用一些松散的规则将Environment属性绑定到@ConfigurationProperties beans上,因此不需要在Environment属性名和bean属性名之间进行确切的匹配。常见的有用例子包括破折号分隔(例如,context-path绑定到contextPath),大小写(例如PORT绑定到port,)环境属性。

For example, given the following @ConfigurationProperties class:

例如,给定下面的@ConfigurationProperties类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ConfigurationProperties(prefix="person")
public class OwnerProperties {

private String firstName;

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

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

}

The following properties names can all be used:

下面的属性名都可以使用:

Table 24.1. relaxed binding

Property Note
person.firstName Standard camel case syntax.
person.first-name Dashed notation, recommended for use in .properties and .yml files.
person.first_name Underscore notation, alternative format for use in .properties and .yml files.
PERSON_FIRST_NAME Upper case format. Recommended when using a system environment variables.

表24.1. 松散绑定

Property Note
person.firstName 标准的驼峰写法
person.first-name 破折号注解,建议在.properties.yml文件中使用
person.first_name 下划线注解,.properties.yml文件中的可替代写法
PERSON_FIRST_NAME 大写形式。当使用系统变量时推荐

24.7.3 Properties conversion

Spring will attempt 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 bean id conversionService) or custom property editors (via a CustomEditorConfigurer bean) or custom Converters (with bean definitions annotated as @ConfigurationPropertiesBinding).

当Spring绑定属性到@ConfigurationProperties beans时,它将试图将外部的应用属性强制转换成正确的类型。如果你需要定制类型转换你可以提供一个ConversionService bean(bean id为conversionService),或定制属性编辑器(通过CustomEditorConfigurer bean),或定制Converters(带有@ConfigurationPropertiesBinding注解的bean定义)。

As this bean is requested very early during the application lifecycle, make sure to limit the dependencies that your ConversionService is using. Typically, any dependency that you require may not be fully initialized at creation time. You may want to rename your custom ConversionService if it’s not required for configuration keys coercion and only rely on custom converters qualified with @ConfigurationPropertiesBindings.

 

bean要求在应用生命周期中的早期,要确保限制ConversionService使用的依赖。通常,任何你要求的依赖可能在创建时不是完整初始化的。如果你定制的ConversionService不要求配置关键字强制转换,你可能想重新命名你定制的ConversionService,并且只依赖满足@ConfigurationPropertiesBindings的定制转换器。

24.7.4 @ConfigurationProperties Validation

Spring Boot will attempt to validate external configuration, by default using JSR-303 (if it is on the classpath). You can simply add JSR-303 javax.validation constraint annotations to your @ConfigurationProperties class:

Spring Boot会试图验证外部化配置,默认使用JSR-303(如果它在classpath中)。你可以简单的添加JSR-303 javax.validation约束注解到你的@ConfigurationProperties类中:

1
2
3
4
5
6
7
8
9
@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {

@NotNull
private InetAddress remoteAddress;

// ... getters and setters

}

In order to validate values of nested properties, you must annotate the associated field as @Valid to trigger its validation. For example, building upon the above ConnectionProperties example:

为了验证嵌入的属性值,你必须注解相关的字段作为@Valid来触发它的校验。例如,在上面的ConnectionProperties例子上构建:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {

@NotNull
@Valid
private RemoteAddress remoteAddress;

// ... getters and setters

public static class RemoteAddress {

@NotEmpty
public String hostname;

// ... getters and setters

}

}

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 allows the bean to be created without having to instantiate the @Configuration class. This avoids any problems that may be caused by early instantiation. There is a property validation sample so you can see how to set things up.

通过创建一个称为configurationPropertiesValidator的bean定义,你也可以添加定制的Spring Validator@Bean方法应该声明静态的。配置属性验证器在应用生命周期的早期创建,声明@Bean方法为静态方法,允许不必实例化@Configuration类就创建bean。这避免了任何早期实例化可能引起的问题。这儿有一个属性验证的例子因此你可以看一下怎样设置它。

The spring-boot-actuator module includes an endpoint that exposes all @ConfigurationProperties beans. Simply point your web browser to /configprops or use the equivalent JMX endpoint. See the Production ready features. section for details.

 

spring-boot-actuator模块包含一个端点,这个端点将公开所有的@ConfigurationProperties beans。简单的将你的web浏览器指向/configprops或用等价的JMX端点。更多细节请看产品级功能。

24.7.5 @ConfigurationProperties vs. @Value

@Value is a core container feature and it does not provide the same features as type-safe Configuration Properties. The table below summarizes the features that are supported by @ConfigurationProperties and @Value:

@Value是一种核心的容器功能,它不能作为类型安全配置属性提供同样的功能。下面的表中总结了@ConfigurationProperties@Value支持的功能:

Feature @ConfigurationProperties @Value
Relaxed binding Yes No
Meta-data support Yes No
SpEL evaluation No Yes
功能 @ConfigurationProperties @Value
松散绑定 Yes No
元数据支持 Yes No
SpEL评估 No Yes

If you define a set of configuration keys for your own components, we recommend you to group them in a POJO annotated with @ConfigurationProperties. Please also be aware that since @Value does not support relaxed binding, it isn’t a great candidate if you need to provide the value using environment variables.

如果你为自己的组件定义了一些配置关键字,我们建议你将它们分组到带有@ConfigurationProperties注解的POJO中。也请注意@Value不支持松散绑定,如果你需要用环境变量提供值,它不是一个好的选择。

Finally, while you can write a SpEL expression in @Value, such expressions are not processed from Application property files.

最后,虽然你可以在@Value中写表达式,但这种表达式不能从应用属性文件中处理。

如果有收获,可以请我喝杯咖啡!