![]() |
睿智的钢笔 · XMLParser的依赖包是什么 - CSDN文库· 4 月前 · |
![]() |
睿智的火锅 · SQL union ...· 1 年前 · |
![]() |
拉风的蟠桃 · 在地图中测量数据点与位置之间的距离 - ...· 1 年前 · |
![]() |
高大的蟠桃 · PHP 获取当天 凌晨 ...· 1 年前 · |
Spring Boot lets you externalize your configuration so that 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 by using the
@Value
annotation, accessed through Spring’s
Environment
abstraction, or be
bound to structured objects
through
@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-devtools.properties
when devtools is active).
@TestPropertySource
annotations on your tests.
properties
attribute on your tests.
Available on
@SpringBootTest
and the
test annotations for testing a particular slice of your application
.
SPRING_APPLICATION_JSON
(inline JSON embedded in an environment variable or system property).
ServletConfig
init parameters.
ServletContext
init parameters.
java:comp/env
.
System.getProperties()
).
RandomValuePropertySource
that has properties only in
random.*
.
application-{profile}.properties
and YAML variants).
application-{profile}.properties
and YAML variants).
application.properties
and YAML variants).
application.properties
and YAML variants).
@PropertySource
annotations on your
@Configuration
classes.
Please note that such property sources are not added to the
Environment
until the application context is being refreshed.
This is too late to configure certain properties such as
logging.*
and
spring.main.*
which are read before refresh begins.
SpringApplication.setDefaultProperties
).
To provide a concrete example, suppose you develop a
@Component
that uses a
name
property, as shown in the following example:
import org.springframework.stereotype.*; import org.springframework.beans.factory.annotation.*; @Component public class MyBean { @Value("${name}") private String name; // ... }
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"
).
|
Tip |
---|---|
The
$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar
In the preceding example, you end up with
$ java -Dspring.application.json='{"name":"test"}' -jar myapp.jar You can also supply the JSON by using a command line argument, as shown in the following example: $ java -jar myapp.jar --spring.application.json='{"name":"test"}'
You can also supply the JSON as a JNDI variable, as follows:
|
|
Note |
---|---|
You can also use YAML ('.yml') files as an alternative to '.properties'. |
$ java -jar myproject.jar --spring.config.name=myproject
The following example shows how to specify two locations:
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
|
Warning |
---|---|
|
|
Note |
---|---|
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,
|
|
Note |
---|---|
If your application runs in a container, then JNDI properties (in
|
|
Note |
---|---|
If you have specified any files in
|
app.name=MyApp app.description=${app.name} is a Spring Boot application
|
Tip |
---|---|
You can also use this technique to create “short” variants of existing Spring Boot properties. See the Section 77.4, “Use ‘Short’ Command Line Arguments” how-to for details. |
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
Section 76.3, “Customize the Environment or ApplicationContext Before It Starts”
for details.
If you’re looking for a secure way to store credentials and passwords, the Spring Cloud Vault project provides support for storing externalized configuration in HashiCorp Vault .
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.
|
Note |
---|---|
If you use “Starters”, SnakeYAML is automatically provided by
|
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
The preceding example would be transformed into the following properties:
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
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
@ConfigurationProperties(prefix="my") public class Config { private List<String> servers = new ArrayList<String>(); public List<String> getServers() { return this.servers; }
server: address: 192.168.1.100 spring: profiles: development server: address: 127.0.0.1 spring: profiles: production & eu-central server: address: 192.168.1.120
|
Note |
---|---|
|
server: port: 8000 spring: profiles: default security: user: password: weak
server: port: 8000 spring: security: user: password: weak
server: port: 8000 spring: profiles: "!test" security: user: password: "secret"
|
Tip |
---|---|
We recommend that you don’t mix profile-specific YAML files and multiple YAML documents. Stick to using only one of them. |
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) { ... } }
The preceding POJO defines the following properties:
acme.enabled
, with a value of
false
by default.
acme.remote-address
, with a type that can be coerced from
String
.
acme.security.username
, with a nested "security" object whose name is determined by the name of the property.
In particular, the return type is not used at all there and could have been
SecurityProperties
.
acme.security.password
.
acme.security.roles
, with a collection of
String
.
|
Note |
---|---|
The properties that map to
|
|
Note |
---|---|
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:
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. Finally, only standard Java Bean properties are considered and binding on static properties is not supported. |
|
Tip |
---|---|
See also the
differences between
|
@Configuration @EnableConfigurationProperties(AcmeProperties.class) public class MyConfiguration { }
|
Note |
---|---|
When the
The bean name in the example above is
|
@Component @ConfigurationProperties(prefix="acme") public class AcmeProperties { // ... see the preceding example }
# application.yml acme: remote-address: 192.168.1.1 security: username: admin roles: - USER - ADMIN # additional configuration as required
@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()); // ... }
|
Tip |
---|---|
Using
|
As an example, consider the following
@ConfigurationProperties
class:
@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; }
With the preceding code, the following properties names can all be used:
|
Note |
---|---|
The
|
Table 24.2. relaxed binding rules per property source
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.
|
Numeric values surrounded by underscores, such as
|
System properties |
Camel case, kebab case, or underscore notation |
Standard list syntax using
|
|
Tip |
---|---|
We recommend that, when possible, properties are stored in lower-case kebab format, such as
|
When binding to
Map
properties, if the
key
contains anything other than lowercase alpha-numeric characters or
-
, you need to use the bracket notation so that the original value is preserved.
If the key is not surrounded by
[]
, any characters that are not alpha-numeric or
-
are removed.
For example, consider binding the following properties to a
Map
:
acme: map: "[/key1]": value1 "[/key2]": value2 /key3: value3
The properties above will bind to a
Map
with
/key1
,
/key2
and
key3
as the keys in the map.
|
Note |
---|---|
For YAML files, the brackets need to be surrounded by quotes for the keys to be parsed properly. |
When lists are configured in more than one place, overriding works by replacing the entire list.
@ConfigurationProperties("acme") public class AcmeProperties { private final List<MyPojo> list = new ArrayList<>(); public List<MyPojo> getList() { return this.list; }
Consider the following configuration:
acme: list: - name: my name description: my description spring: profiles: dev acme: list: - name: my another name
acme: list: - name: my name description: my description - name: another name description: another description spring: profiles: dev acme: list: - name: my another name
@ConfigurationProperties("acme") public class AcmeProperties { private final Map<String, MyPojo> map = new HashMap<>(); public Map<String, MyPojo> getMap() { return this.map; }
Consider the following configuration:
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
|
Note |
---|---|
The preceding merging rules apply to properties from all property sources and not just YAML files. |
|
Note |
---|---|
As this bean is requested very early during the application lifecycle, make sure to limit the dependencies that your
|
long
representation (using milliseconds as the default unit unless a
@DurationUnit
has been specified)
java.time.Duration
10s
means 10 seconds)
Consider the following example:
@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; }
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
The default unit is milliseconds and can be overridden using
@DurationUnit
as illustrated in the sample above.
|
Tip |
---|---|
If you are upgrading from a previous version that is simply using
|
Consider the following example:
@ConfigurationProperties("app.io") public class AppIoProperties { @DataSizeUnit(DataUnit.MEGABYTES) private DataSize bufferSize = DataSize.ofMegabytes(2); private DataSize sizeThreshold = DataSize.ofBytes(512); public DataSize getBufferSize() { return this.bufferSize; public void setBufferSize(DataSize bufferSize) { this.bufferSize = bufferSize; public DataSize getSizeThreshold() { return this.sizeThreshold; public void setSizeThreshold(DataSize sizeThreshold) { this.sizeThreshold = sizeThreshold; }
You can also use any of the supported units. These are:
|
Tip |
---|---|
If you are upgrading from a previous version that is simply using
|
@ConfigurationProperties(prefix="acme") @Validated public class AcmeProperties { @NotNull private InetAddress remoteAddress; // ... getters and setters }
|
Tip |
---|---|
You can also trigger validation by annotating the
|
@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 }