24. 外部化配置
Spring Boot允许你外部化你的配置,这样你就可以在不同的环境中使用相同的应用程序代码,你可以使用properties文件、YAML文件、环境变量和命令行参数来外部化配置,属性值可以通过使用@Value
注解直接注入到你的bean中,通过Spring的Environment
抽象访问,或者通过@ConfigurationProperties
绑定到结构化对象。
Spring Boot使用一种非常特殊的PropertySource
命令,该命令旨在允许对值进行合理的覆盖,属性按以下顺序考虑:
-
Devtools全局设置属性在你的主目录(
~/.spring-boot-devtools.properties
当devtools处于激活状态时。 - 测试中的@TestPropertySource注解
- 测试中的@SpringBootTest#properties注解属性
- 命令行参数
- 来自
SPRING_APPLICATION_JSON
(嵌入在环境变量或系统属性中的内联JSON)的属性 -
ServletConfig
初始化参数 -
ServletContext
初始化参数 -
java:comp/env
中的JNDI属性 - Java系统属性(
System.getProperties()
) - 操作系统环境变量
- 一个只有
random.*
属性的RandomValuePropertySource
- 在你的jar包之外的特殊配置文件的应用程序属性(
application-{profile}.properties
和YAML
变体) - 在jar中打包的特殊配置文件的应用程序属性(
application-{profile}.properties
和YAML
变体) - 在你的jar包之外的应用程序属性(
application.properties
和YAML
变体) - 打包在jar中的应用程序属性(
application.properties
和YAML
变体) -
@PropertySource注解在你的
@Configuration
类上 - 默认属性(通过设置
SpringApplication.setDefaultProperties
指定)
为了提供一个具体的示例,假设你开发了一个使用name
属性的@Component
,如下例所示:
import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;
@Component
public class MyBean {
@Value("${name}")
private String name;
// ...
}
在你的应用程序类路径(例如,在jar包中)你可以有一个application.properties
文件为name
提供一个合理的默认属性值。在新环境中运行时,可以在你的jar包之外提供一个application.properties
以覆盖name
。对于一次性测试,你可以使用特定的命令行开关启动(例如,java -jar app.jar --name=“Spring”
)。
SPRING_APPLICATION_JSON
属性可以在带有环境变量的命令行上提供,例如,你可以在UN*X shell中使用以下一行:
$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar
在前面的示例中,在SpringEnvironment
中你最终得到了acme.name=test
,你也可以提供JSON作为spring.applicatio.json
在系统属性中,如下例所示:
$ java -Dspring.application.json='{"name":"test"}' -jar myapp.jar
你还可以使用命令行参数来提供JSON,如下面的示例所示:
$ java -jar myapp.jar --spring.application.json='{"name":"test"}'
你还可以将JSON作为JNDI变量提供,如下所示:java:comp/env/spring.application.json
。
24.1 配置随机值
RandomValuePropertySource
用于注入随机值(例如,在secrets或测试用例中),它可以生成integer
、long
、uuid
或string
,如下面的示例所示:
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*
语法是OPEN value (,max) CLOSE
在OPEN,CLOSE
中是任何字符并且value,max
是整数。如果提供了max
,那么value
就是最小值,max
是最大值(唯一的)。
24.2 访问命令行属性
在默认情况下,SpringApplication
会转换任何命令行选项参数(也就是说,参数从--
开始,像--server.port=9000
)到一个property
,并将它们添加到Spring Environment
中,如前所述,命令行属性总是优先于其他属性源。
如果不希望将命令行属性添加到Environment
中,你可以使用SpringApplication.setAddCommandLineProperties(false)
禁用它们。
24.3 应用程序属性文件
SpringApplication
在以下位置从application.properties
文件加载属性并将它们添加到Spring Environment
:
- 当前目录子目录的
/config
- 当前目录
- 类路径下
/config
包 - 类路径的根目录
列表按优先顺序排序(在列表中较高的位置定义的属性覆盖在较低位置定义的属性)。
你还可以使用YAML ('.yml'
)文件作为'.properties'的替代。
如果你不喜欢application.properties
作为配置文件名,可以通过指定spring.config.name
环境属性切换到另一个文件名,你还可以使用spring.config.location
环境属性来引用一个显式的位置(它是一个逗号分隔的目录位置或文件路径列表),下面的示例演示如何指定不同的文件名:
$ java -jar myproject.jar --spring.config.name=myproject
下面的示例演示如何指定两个位置:
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/
override.properties
spring.config.name
和spring.config.location
很早就被用于确定哪些文件必须被加载,因此它们必须被定义为环境属性(通常是一个OS环境变量、一个系统属性或一个命令行参数)。
如果spring.config.location
包含目录(相对于文件),它们应该以/
结束(并且在运行时,附加的名字来自spring.config.name
之前被加载,包括特殊配置文件的文件名)。spring.config.location
中指定的文件是按原样使用的,不支持特殊配置文件的变体,并且被任何特殊配置文件的属性覆盖。
配置位置按相反顺序搜索,默认情况下,配置的位置是classpath:/
、classpath:/config/
、file:./
、file:./config/
。由此产生的搜索顺序如下:
file:./config/
file:./
classpath:/config/
classpath:/
当自定义配置位置使用spring.config.location
配置时,它们替换默认的位置。例如,如果spring.config.location
配置值为classpath:/custom-config/
、file:./custom-config/
,搜索顺序如下:
file:./custom-config/
classpath:custom-config/
或者,当自定义配置位置使用spring.config.additional-location
配置时,除了默认位置外,还使用它们,在默认位置之前搜索额外的位置。例如,如果额外位置classpath:/custom-config/
、file:./custom-config/
被配置,搜索顺序如下:
file:./custom-config/
classpath:custom-config/
file:./config/
file:./
classpath:/config/
classpath:/
这个搜索排序允许你在一个配置文件中指定默认值,然后在另一个配置文件中选择性地覆盖这些值。你可以在application.properties
为你的应用程序提供默认值(或你在spring.config.name
中选择的其他basename)位于默认位置之一。这些默认值可以在运行时被重写,并在一个定制的位置中放置一个不同的文件。
如果你使用环境变量而不是系统属性,大多数操作系统都不允许使用周期分隔的键名,但是你可以使用下划线(例如,SPRING_CONFIG_NAME
而不是spring.config.name
)。
如果应用程序在容器中运行,那么可以使用JNDI属性(在java:comp/env
)或servlet上下文初始化参数,而不是环境变量或系统属性。
24.4 特殊配置文件的属性
除了application.properties
文件,特殊配置文件的属性也可以通过以下命名约定来定义:application-{profile}.properties
。Environment
有一组默认配置文件(默认情况下是[default]
),如果没有设置活动配置文件,则使用默认配置文件。换句话说,如果没有显式激活配置文件,则加载application-default.properties
中的属性。
特殊配置文件的属性从与标准application.properties
相同的位置加载,特殊配置文件的文件总是覆盖非特定的文件,无论特殊配置文件的文件是在打包的jar内部还是外部。
如果多个特殊配置文件,则使用应用最后一个的策略,例如,由spring.profiles.active
属性添加的特殊配置文件在通过SpringApplication
API配置的配置文件之后添加,因此优先级更高。
如果在spring.config.locaction
中指定了任何文件,不考虑这些文件的特定配置文件的变体。如果你还想同时使用特殊配置文件,在spring.config.location
中使用目录
24.5 属性中的占位符
application.properties
中的值在使用时通过现有Environment
进行过滤,因此你可以返回到以前定义的值(例如,来自系统属性)。
app.name=MyApp
app.description=${app.name} is a Spring Boot application
你还可以使用此技术来创建现有Spring boot属性的“Short”变体,详细信息请参阅第74.4节“使用‘Short’命令行参数”。
24.6 使用YAML代替属性
YAML是JSON的超集,因此是指定分层配置数据的一种方便的格式,只要类路径上有SnakeYAML库,SpringApplication
类就会自动支持YAML作为属性的替代。
如果你使用“Starters”,SnakeYAML将由spring-boot-starter
自动提供。
24.6.1 加载YAML
Spring框架提供了两个方便的类,可以用来加载YAML文档。YamlPropertiesFactoryBean
以属性装载YAML,而YamlMapFactoryBean
以Map
的形式装载YAML。
例如,参考以下YAML文档:
environments:
dev:
url: http://dev.example.com
name: Developer Setup
prod:
url: http://another.example.com
name: My Cool App
前面的示例将转换为以下属性:
environments.dev.url=http://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=http://another.example.com
environments.prod.name=My Cool App
YAML列表表示为[index]
解释器的属性键,例如,参考以下YAML:
my:
servers:
- dev.example.com
- another.example.com
前面的例子将被转换为这些属性:
my.servers[0]=dev.example.com
my.servers[1]=another.example.com
通过使用Spring Boot的Binder
工具(这是@ConfigurationProperties
所做的)来绑定到类似的属性,你需要在目标bean中有一个java.util.List
(或Set
)属性并且还需要提供一个setter或使用变量初始化它。例如,下面的示例绑定到前面显示的属性:
@ConfigurationProperties(prefix="my")
public class Config {
private List<String> servers = new ArrayList<String>();
public List<String> getServers() {
return this.servers;
}
}
24.6.2 将YAML公开为Spring环境中的属性
YamlPropertySourceLoader
类可用于在Spring Environment
中将YAML公开为PropertySource
,这样做可以使用带有占位符语法的@Value
注解来访问YAML属性。
24.6.3 多个YAML配置文件
你可以使用spring.profiles
键在单个文件中指定多个特殊配置YAML文档来指示你文档何时应用,如下所示:
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production
server:
address: 192.168.1.120
在前面的例子中,如果development
配置文件是激活的,server.address
属性是127.0.0.1
。类似地,如果production
配置文件是激活的,server.address
属性是192.168.1.120
。如果不启用development
和production
配置文件,则属性的值为192.168.1.100
。
如果在应用程序上下文启动时没有显式激活,默认配置文件被激活。因此,在接下来的YAML中,我们为仅在“默认”配置文件中可用的spring.security.user.password
设置了一个值:
server:
port: 8000
---
spring:
profiles: default
security:
user:
password: weak
然而,在下面的示例中,密码总是被设置,因为它没有附加到任何配置文件中,而且将在所有其他配置文件中显式地设置被重置:
server:
port: 8000
spring:
security:
user:
password: weak
使用spring.profiles
元素指定的Spring配置文件可以选择性的使用!
字符否定。如果为单个文档指定了否定的和非否定的配置文件,则至少必须匹配一个非否定的配置文件,并且不能匹配任何否定的配置文件。
24.6.4 YAML的缺点
YAML文件不能被@PropertySource
注解加载,因此,在需要以这种方式加载值的情况下,需要使用属性文件。
24.7 类型安全的配置属性文件
使用@Value(“${property}”)
注解注入配置属性有时会很麻烦,尤其是当你处理多个属性或你的数据本质上是层次化的时候,Spring Boot提供了另一种处理属性的方法,该方法允许强类型bean管理和验证应用程序的配置。
package com.example;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("acme")
public class AcmeProperties {
private boolean enabled;
private InetAddress remoteAddress;
private final Security security = new Security();
public boolean isEnabled() { ... }
public void setEnabled(boolean enabled) { ... }
public InetAddress getRemoteAddress() { ... }
public void setRemoteAddress(InetAddress remoteAddress) { ... }
public Security getSecurity() { ... }
public static class Security {
private String username;
private String password;
private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
public String getUsername() { ... }
public void setUsername(String username) { ... }
public String getPassword() { ... }
public void setPassword(String password) { ... }
public List<String> getRoles() { ... }
public void setRoles(List<String> roles) { ... }
}
}
前一个POJO定义了以下属性:
-
acme.enabled
,默认值为false
-
acme.remote-address
,可以从String
强转的类型 -
acme.security.username
,使用嵌套的“ security”对象,该对象的名称由属性的名称决定,特别是,返回类型根本不使用,并且可能是SecurityProperties
。 acme.security.password
-
acme.security.roles
,使用一个String
集合
getter和setter通常是强制性的,因为绑定是通过标准的Java bean属性描述符,就像在Spring MVC中一样,在以下情况下可以省略setter:
- Map,只要初始化了它们,就需要一个getter,但不一定需要setter,因为绑定器可以对它们进行转变。
- 可以通过索引(通常是YAML)或使用单个逗号分隔值(属性)来访问集合和数组,在后一种情况下,setter是必需的。我们建议始终为此类类型添加一个setter,如果初始化一个集合,请确保它不是不可变的(如前面的示例所示)。
- 如果初始化嵌套POJO属性(如前面示例中的
Security
字段),则不需要setter,如果你希望绑定器使用它的默认构造函数来动态创建实例,那么你需要一个setter。有些人使用Lombok项目自动添加getter和setter,确保Lombok没有为此类类型生成任何特定的构造函数,因为容器会自动使用它来实例化对象。
最后,只考虑标准的Java Bean属性,不支持对静态属性的绑定。
还可以查看@Value
和@ConfigurationProperties
之间的差异。
你还需要列出要在@EnableConfigurationProperties
注解中注册的属性类,如下例所示:
@Configuration
@EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {
}
当以@ConfigurationProperties
这种方式注册bean时,bean有一个常规名称:<prefix>-<fqn>
,其中<prefix>
是在@ConfigurationProperties
注解中指定的环境key前缀,<fqn>
是bean的完全限定名,如果注解不提供任何前缀,则只使用bean的完全限定名。上面示例中的bean名称是
acme-com.example.AcmeProperties
。
即使前面的配置为AcmeProperties
创建了一个常规bean,我们建议@ConfigurationProperties
只处理环境,特别是从上下文中不注入其他bean。话虽如此,@EnableConfigurationProperties
注解也自动应用于你的项目,使任何已添加@ConfigurationProperties
注解的bean都可以从Environment
中配置。你可以通过确保AcmeProperties
已经是一个bean来简化MyConfiguration
,如下面的示例所示:
@Component
@ConfigurationProperties(prefix="acme")
public class AcmeProperties {
// ... see the preceding example
}
这种配置风格与SpringApplication
外部YAML配置配合得特别好,如下例所示:
# application.yml
acme:
remote-address: 192.168.1.1
security:
username: admin
roles:
- USER
- ADMIN
# additional configuration as required
要使用@ConfigurationProperties
bean,可以像其他bean一样对它们进行注入,如下例所示:
@Service
public class MyService {
private final AcmeProperties properties;
@Autowired
public MyService(AcmeProperties properties) {
this.properties = properties;
}
//...
@PostConstruct
public void openConnection() {
Server server = new Server(this.properties.getRemoteAddress());
// ...
}
}
使用@ConfigurationProperties
还可以生成可以被IDE使用的元数据文件,为你自己的键提供自动完成。详细信息请参阅附录B,配置元数据附录。
24.7.1 第三方配置
除了使用@ConfigurationProperties
来注解类之外,还可以在公开的@Bean
方法中使用它,当你希望将属性绑定到控件之外的第三方组件时,这样做特别有用。
要从Environment
属性配置bean,请向其bean注册中添加@ConfigurationProperties
,如下例所示:
@ConfigurationProperties(prefix = "another")
@Bean
public AnotherComponent anotherComponent() {
...
}
用another
前缀定义的任何属性都被映射到与前面的AcmeProperties
示例类似的另一个组件bean。
24.7.2 宽松绑定
Spring Boot使用一些宽松的规则将Environment
属性绑定到@ConfigurationProperties
bean,因此不需要在Environment
属性名和bean属性名之间进行精确匹配,这很有用的常见示例包括:分体环境属性(例如,context-path
绑定到contextPath
)和大写的环境属性(例如,PORT
绑定到port
)。
例如,参考下面的@ConfigurationProperties
类:
@ConfigurationProperties(prefix="acme.my-project.person")
public class OwnerProperties {
private String firstName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
在前面的示例中,可以使用以下属性名称:
属性 | 提示 |
---|---|
acme.my-project.person.first-name |
连接符形式,建议在.properties 和.yml 文件中使用 |
acme.myProject.person.firstName |
标准的驼峰式大小写语法 |
acme.my_project.person.first_name |
下划线表示法,这是在.properties 和.yml 文件中使用的另一种格式 |
ACME_MYPROJECT_PERSON_FIRSTNAME |
在使用系统环境变量时推荐使用大写格式 |
注解的prefix
值必须使用连接符形式(小写并且使用-
分隔,如acme.my-project.person
)。
表24.2,放宽了每个属性源的绑定规则
属性源 | 样例 | 列表 |
---|---|---|
属性文件 | 驼峰式大小写,连接符大小写,或下划线符号 | 使用[] 或逗号分隔值的标准列表语法 |
YAML文件 | 驼峰式大小写,连接符大小写,或下划线符号 | 标准的YAML列表语法或逗号分隔的值 |
环境变量 | 以下划线作为分隔符的大写格式,不应该在属性名中使用_
|
由下划线包围的数值,例如MY_ACME_1_OTHER = my.acme[1].other
|
系统属性 | 驼峰式大小写,连接符大小写,或下划线符号 | 使用[] 或逗号分隔值的标准列表语法 |
我们建议,在可能的情况下,属性以小写的连接符格式存储,例如my.property-name=acme
在绑定到Map
属性时,如果key
不包含小写字母数字字符或-
,则需要使用括号符号,以便保留原始值。如果键没有被[]
包围,任何非字母数字或-
的字符都会被删除,例如,考虑将以下属性绑定到Map
:
acme:
map:
"[/key1]": value1
"[/key2]": value2
/key3: value3
上面的属性将绑定到以/key1
、/key2
和key3
作为Map中的键的Map
。
24.7.3 合并复杂类型
当在多个地方配置列表时,通过替换整个列表来重写。
例如,假设一个MyPojo
对象的name
和description
属性默认为null
,下面的示例公开了来自AcmeProperties
的MyPojo
对象列表:
@ConfigurationProperties("acme")
public class AcmeProperties {
private final List<MyPojo> list = new ArrayList<>();
public List<MyPojo> getList() {
return this.list;
}
}
参考如下配置:
acme:
list:
- name: my name
description: my description
---
spring:
profiles: dev
acme:
list:
- name: my another name
如果dev
配置文件不是激活的,AcmeProperties.list
包含一个MyPojo
条目,正如前面定义的。如果启用了dev
配置文件,然而,该列表仍然只包含一个条目,(以my another name
的名称和null
的描述),此配置不向列表添加第二个MyPojo
实例,也不合并条目。
当一个List
在多个配置文件中指定时,使用具有最高优先级的(且仅使用该优先级),参考下面的例子:
acme:
list:
- name: my name
description: my description
- name: another name
description: another description
---
spring:
profiles: dev
acme:
list:
- name: my another name
在前面的例子,如果dev
配置文件是激活的,AcmeProperties.list
包含一个MyPojo
条目(以my another name
作为name和null
的description),对于YAML,可以使用逗号分隔的列表和YAML列表完全覆盖列表的内容。
对于Map
属性,你可以使用来自多个源的属性值进行绑定,但是,对于多个源中的相同属性,使用优先级最高的属性。下面的示例公开了AcmeProperties
的Map<String, MyPojo>
:
@ConfigurationProperties("acme")
public class AcmeProperties {
private final Map<String, MyPojo> map = new HashMap<>();
public Map<String, MyPojo> getMap() {
return this.map;
}
}
参考如下配置:
acme:
map:
key1:
name: my name 1
description: my description 1
---
spring:
profiles: dev
acme:
map:
key1:
name: dev name 1
key2:
name: dev name 2
description: dev description 2
如果dev
配置文件不是激活的,AcmeProperties.map
包含一个键key1
的条目(一个my name 1
的name和一个my description 1
的description)。如果启用了dev
配置文件,然而,map
包含键key1
(name为dev name 1
,description为my description 1
)和key2
(name为dev name 2
,description为dev description 2
)的两个条目。
前面的合并规则适用于来自所有属性源的属性,而不仅仅是YAML文件。
24.7.4 属性转换
Spring Boot试图在绑定到@ConfigurationProperties
bean时将外部应用程序属性强制转换到正确的类型,如果需要自定义类型转换,你可以提供一个ConversionService
bean(一个名为ConversionService
的bean)或自定义属性编辑器(通过一个CustomEditorConfigurer
bean)或自定义Converters
(使用@ConfigurationPropertiesBinding
注解定义的bean)。
因为这个bean在应用程序生命周期的早期就被请求,确保限制你的ConversionService
正在使用的依赖项。
通常,你需要的任何依赖项在创建时可能不会被完全初始化,如果配置键强制转换不需要自定义ConversionService
,并且只依赖于使用@ConfigurationPropertiesBinding
限定的自定义转换器,那么你可能希望重命名自定义转换服务。
转换持续时间
Spring Boot支持表示持续时间,如果你公开一个java.time.Duration
属性,在应用程序属性中有以下格式:
- 一个常规的
long
表示(使用毫秒作为默认单位,除非指定了@DurationUnit
) - 使用java.util.Duration的标准的ISO-8601格式
- 一个更可读的格式,其中的值和单位是耦合的(例如,
10s
意味着10秒)
参考下面的例子:
@ConfigurationProperties("app.system")
public class AppSystemProperties {
@DurationUnit(ChronoUnit.SECONDS)
private Duration sessionTimeout = Duration.ofSeconds(30);
private Duration readTimeout = Duration.ofMillis(1000);
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
,PT30S
和30s
都是等价的,可以在以下任何形式中指定500ms的读超时:500
,PT0.5S
和500ms
。
你还可以使用任何受支持的单元,这些都是:
- 纳秒使用
ns
- 毫秒使用
ms
- 秒使用
s
- 分钟使用
m
- 小时使用
h
- 天使用
d
默认的单位是毫秒,可以使用@DurationUnit
覆盖,如上面的示例所示。
如果你正在升级以前的版本,只是使用Long
来表示持续时间,如果不是在切换到Duration
时的毫秒数,确保定义单元(使用@DurationUnit
)。这样做可以提供透明的升级路径,同时支持更丰富的格式。
24.7.5 @ConfigurationProperties Validation
每当使用Spring的@validate
注解@ConfigurationProperties
类时,Spring Boot都会尝试验证这些类。你可以直接在配置类上使用JSR-303 javax.validation
约束注解。为此,请确保在你的类路径上有一个兼容的JSR-303实现,然后向你的字段添加约束注解,如下面的示例所示:
@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {
@NotNull
private InetAddress remoteAddress;
// ... getters and setters
}
你还可以通过注解@Bean
方法来触发验证,该方法使用@Validated
创建配置属性。
尽管嵌套属性在绑定时也会被验证,将相关字段注解为@Valid
是很好的实践,这确保即使没有找到嵌套属性,也会触发验证。以下示例基于前面的AcmeProperties
示例:
@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {
@NotNull
private InetAddress remoteAddress;
@Valid
private final Security security = new Security();
// ... getters and setters
public static class Security {
@NotEmpty
public String username;
// ... getters and setters
}
}
你还可以通过创建一个名为configurationPropertiesValidator
的bean定义来添加一个定制的Spring Validator
。@Bean
方法应该声明为static
,配置属性验证器是在应用程序生命周期的早期创建的,并且将@Bean
方法声明为静态,这样就可以创建bean,而不必实例化@Configuration
类。这样做可以避免早期实例化可能导致的任何问题。这里有一个属性验证示例,展示了如何设置。
spring-boot-actuator
模块包含公开所有@ConfigurationProperties
bean的端点,将web浏览器指向/actuator/configprops
或使用等效的JMX端点。有关详细信息,请参阅“生产就绪特性”一节。
24.7.6 @ConfigurationProperties和@Value
@Value
注解是一个核心容器特性,它不提供与类型安全配置属性相同的特性,下表总结了@ConfigurationProperties
和@Value
支持的特性:
特性 | @ConfigurationProperties |
@Value |
---|---|---|
宽松绑定 | YES | NO |
元数据支持 | YES | NO |
SpEL 评估 |
NO | YES |
如果你为自己的组件定义了一组配置键,我们建议你将它们分组到带有@ConfigurationProperties
注解的POJO中。你还应该注意,由于@Value
不支持宽松绑定,因此如果你需要通过使用环境变量来提供值,那么它不是一个很好的选择。
最后,当你可以在@Value
中编写SpEL
表达式,这些表达式不会从应用程序属性文件中处理。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。