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.
Spring Boot uses a very particular PropertySource order that is designed to allow
sensible overriding of values, properties are considered in the the following order:
System.getProperties()).
java:comp/env
RandomValuePropertySource that only has properties in random.*.
application.properties
including YAML and profile variants).
application.properties
including YAML and profile variants).
@PropertySource annotations on your @Configuration classes.
SpringApplication.setDefaultProperties).
To provide a concrete example, suppose you develop a @Component that uses a
name property:
import org.springframework.stereotype.* import org.springframework.beans.factory.annotation.* @Component public class MyBean { @Value("${name}") private String name; // ... }
You can bundle an application.properties inside your jar that provides a sensible
default name. When running in production, an application.properties can be provided
outside of your jar that overrides name; and for one-off testing, you can launch with
a specific command line switch (e.g. java -jar app.jar --name="Spring").
The RandomValuePropertySource is useful for injecting random values (e.g. into secrets
or test cases). It can produce integers, longs or strings, e.g.
my.secret=${random.value} my.number=${random.int} my.bignumber=${random.long} 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).
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.
If you don’t want command line properties to be added to the Environment you can disable
them using SpringApplication.setAddCommandLineProperties(false).
SpringApplication will load properties from application.properties files in the
following locations and add them to the Spring Environment:
/config subdir of the current directory.
/config package
The list is ordered by precedence (locations higher in the list override lower items).
![]() | Note |
|---|---|
|
You can also use YAML (.yml) files as an alternative to .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).
$ java -jar myproject.jar --spring.config.name=myproject
or
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
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). The default search path classpath:,classpath:/config,file:,file:config/
is always used, irrespective of the value of spring.config.location. 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.
![]() | Note |
|---|---|
|
if you use environment variables not system properties, most operating systems
disallow period-separated key names, but you can use underscores instead (e.g.
|
![]() | Note |
|---|---|
|
If you are running in a container then JNDI properties (in |
In addition to application.properties files, profile specific properties can also be
defined using the naming convention application-{profile}.properties.
Profile specific properties are loaded from the same locations as standard
application.properties, with profiles specific files overriding the default ones.
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).
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 58.3, “Use “short” command line arguments” how-to for details. |
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.
![]() | Note |
|---|---|
|
If you use “starter POMs” SnakeYAML will be automatically provided via
|
Spring Boot 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.
For example, the following YAML document:
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:
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:
my: servers: - dev.bar.com - foo.bar.com
Would be transformed into these properties:
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
@ConfigurationProperties(prefix="my") public class Config { private List<String> servers = new ArrayList<String>(); public List<String> getServers() { return this.servers; } }
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.
You can specify multiple profile-specific YAML document in a single file by
by using a spring.profiles key to indicate when the document applies. For example:
server: address: 192.168.1.100 --- spring: profiles: development server: address: 127.0.0.1 --- spring: profiles: production server: address: 192.168.1.120
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:
@Component @ConfigurationProperties(prefix="connection") public class ConnectionSettings { private String username; private InetAddress remoteAddress; // ... getters and setters }
When the @EnableConfigurationProperties annotation is applied to your @Configuration,
any beans annotated with @ConfigurationProperties will be automatically configured
from the Environment properties. This style of configuration works particularly well
with the SpringApplication external YAML configuration:
# 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.
@Service public class MyService { @Autowired private ConnectionSettings connection; //... @PostConstruct public void openConnection() { Server server = new Server(); this.connection.configure(server); } }
It is also possible to shortcut the registration of @ConfigurationProperties bean
definitions by simply listing the properties classes directly in the
@EnableConfigurationProperties annotation:
@Configuration @EnableConfigurationProperties(ConnectionSettings.class) public class MyConfiguration { }
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 underscore separated (e.g. context_path binds to contextPath), and
capitalized (e.g. PORT binds to port) environment properties.
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).
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:
@Component @ConfigurationProperties(prefix="connection") public class ConnectionSettings { @NotNull private InetAddress remoteAddress; // ... getters and setters }
You can also add a custom Spring Validator by creating a bean definition called
configurationPropertiesValidator.
![]() | Tip |
|---|---|
|
The |