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, include Java properties files, YAML files, environment variables, and command-line arguments.
Property values can be injected directly into your beans by using the `@Value` annotation, accessed through Spring's `Environment` abstraction, or be <<features#features.external-config.typesafe-configuration-properties,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 (with values from lower items overriding earlier ones):
. Default properties (specified by setting `SpringApplication.setDefaultProperties`).
. {spring-framework-api}/context/annotation/PropertySource.html[`@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.
. Config data (such as `application.properties` files)
. A `RandomValuePropertySource` that has properties only in `+random.*+`.
. 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 {spring-boot-test-module-api}/context/SpringBootTest.html[`@SpringBootTest`] and the <<features#features.testing.spring-boot-applications.autoconfigured-tests,test annotations for testing a particular slice of your application>>.
. {spring-framework-api}/test/context/TestPropertySource.html[`@TestPropertySource`] annotations on your tests.
. <<using#using.devtools.globalsettings,Devtools global settings properties>> in the `$HOME/.config/spring-boot` directory when devtools is active.
Config data files are considered in the following order:
. <<features#features.external-config.files,Application properties>> packaged inside your jar (`application.properties` and YAML variants).
. <<features#features.external-config.files.profile-specific,Profile-specific application properties>> packaged inside your jar (`application-\{profile}.properties` and YAML variants).
. <<features#features.external-config.files,Application properties>> outside of your packaged jar (`application.properties` and YAML variants).
. <<features#features.external-config.files.profile-specific,Profile-specific application properties>> outside of your packaged jar (`application-\{profile}.properties` and YAML variants).
NOTE: It is recommended to stick with one format for your entire application.
If you have configuration files with both `.properties` and `.yml` format in the same location, `.properties` takes precedence.
To provide a concrete example, suppose you develop a `@Component` that uses a `name` property, as shown in the following example:
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 `env` and `configprops` endpoints can be useful in determining why a property has a particular value.
You can use these two endpoints to diagnose unexpected property values.
See the "<<actuator#actuator.endpoints, Production ready features>>" section for details.
[[features.external-config.command-line-args]]
=== Accessing Command Line Properties
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.
If you do not want command line properties to be added to the `Environment`, you can disable them by using `SpringApplication.setAddCommandLineProperties(false)`.
[[features.external-config.application-json]]
=== JSON Application Properties
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.
When your application starts, any `spring.application.json` or `SPRING_APPLICATION_JSON` properties will be parsed and added to the `Environment`.
For example, the `SPRING_APPLICATION_JSON` property can be supplied on the command line in a UN{asterisk}X shell as an environment variable:
If you are deploying to a classic Application Server, you could also use a JNDI variable named `java:comp/env/spring.application.json`.
NOTE: Although `null` values from the JSON will be added to the resulting property source, the `PropertySourcesPropertyResolver` treats `null` properties as missing values.
This means that the JSON cannot override properties from lower order property sources with a `null` value.
Spring Boot will automatically find and load `application.properties` and `application.yaml` files from the following locations when your application starts:
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`.
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.
TIP: Use the prefix `optional:` if the <<features#features.external-config.files.optional-prefix,locations are optional>> and you don't mind if they don't exist.
WARNING: `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).
NOTE: Both directory and file location values are also expanded to check for <<features#features.external-config.files.profile-specific,profile-specific files>>.
For example, if you have a `spring.config.location` of `classpath:myconfig.properties`, you will also find appropriate `classpath:myconfig-<profile>.properties` files are loaded.
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 `;`.
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/`
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:
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.
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, configprop:spring.config.name[format=envvar] instead of configprop:spring.config.name[]).
See <<features#features.external-config.typesafe-configuration-properties.relaxed-binding.environment-variables>> for details.
NOTE: If your application runs in a servlet container or application server, 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.
By default, when a specified config data location does not exist, Spring Boot will throw a `ConfigDataLocationNotFoundException` and your application will not start.
If you want to specify a location, but you don't mind if it doesn't 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 <<features#features.external-config.files.importing, `spring.config.import`>> declarations.
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.
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.
If a config file location includes the `{asterisk}` 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.
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.
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.
You can use wildcard locations yourself with the `spring.config.location` and `spring.config.additional-location` properties.
NOTE: A wildcard location must contain only one `{asterisk}` and end with `{asterisk}/` for search locations that are directories or `*/<filename>` for search locations that are files.
Locations with wildcards are sorted alphabetically based on the absolute path of the file names.
TIP: Wildcard locations only work with external directories.
You cannot use a wildcard in a `classpath:` location.
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.yml` and `application-prod.yml` will be considered.
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`.
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.
NOTE: Properties files are only ever loaded once.
If you've already directly <<features#features.external-config.files.importing,imported>> a profile specific property files then it won't be imported a second time.
[[features.external-config.files.importing]]
==== Importing Additional Data
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.
For example, you might have the following in your classpath `application.properties` file:
Spring Boot includes pluggable API that allows various different location addresses to be supported.
By default you can import Java Properties, YAML and "`<<features#features.external-config.files.configtree, configuration trees>>`".
Third-party jars can offer support for additional technologies (there's 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 `ConfigDataLocationResolver` and `ConfigDataLoader` classes in the `org.springframework.boot.context.config` package.
When running applications on a cloud platform (such as Kubernetes) you often need to read config values that the platform supplies.
It's not uncommon to use environment variables for such purposes, but this can have drawbacks, especially if the value is supposed to be kept secret.
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 https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#populate-a-volume-with-data-stored-in-a-configmap[`ConfigMaps`] and https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod[`Secrets`].
. 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`'.
For the first case, you can import the YAML or Properties file directly using `spring.config.import` as described <<features#features.external-config.files.importing,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.
As an example, let's imagine that Kubernetes has mounted the following volume:
[indent=0]
----
etc/
config/
myapp/
username
password
----
The contents of the `username` file would be a config value, and the contents of `password` would be a secret.
To import these properties, you can add the following to your `application.properties` or `application.yaml` file:
TIP: The folders under the config tree form the property name.
In the above example, to access the properties as `username` and `password`, you can set `spring.config.import` to `optional:configtree:/etc/config/myapp`.
This will add `db.username`, `db.password`, `mq.username` and `mq.password` properties.
NOTE: 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 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:
The values in `application.properties` and `application.yml` 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}`.
Assuming that the `username` property has not be set elsewhere, `app.description` will have the value `MyApp is a Spring Boot application written by Unknown`.
For example, you might have properties that are only relevant when a specific profile is active.
You can conditionally activate a properties document using `spring.config.activate.*`.
The following activation properties are available:
.activation properties
[cols="1,4"]
|===
| Property | Note
| `on-profile`
| A profile expression that must match for the document to be active.
| `on-cloud-platform`
| The `CloudPlatform` that must be detected for the document to be active.
|===
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:
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 <<howto#howto.application.customize-the-environment-or-application-context>> for details.
If you're looking for a secure way to store credentials and passwords, the https://cloud.spring.io/spring-cloud-vault/[Spring Cloud Vault] project provides support for storing externalized configuration in https://www.vaultproject.io/[HashiCorp Vault].
[[features.external-config.yaml]]
=== Working with YAML
https://yaml.org[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 https://bitbucket.org/asomov/snakeyaml[SnakeYAML] library on your classpath.
NOTE: If you use "`Starters`", SnakeYAML is automatically provided by `spring-boot-starter`.
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).
[[features.external-config.system-environment]]
=== Configuring System Environment Properties
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`.
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.
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.
TIP: See also the <<features#features.external-config.typesafe-configuration-properties.vs-value-annotation,differences between `@Value` and type-safe configuration properties>>.
NOTE: The properties that map to `@ConfigurationProperties` classes available in Spring Boot, which are configured via properties files, YAML files, environment variables etc., are public API but the accessors (getters/setters) of the class itself are not meant to be used directly.
[NOTE]
====
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:
* Maps, as long as they are initialized, need a getter but not necessarily a setter, since they can be mutated by the binder.
* Collections and arrays can be accessed either through an index (typically with YAML) or by using a single comma-separated value (properties).
In the latter case, a setter is mandatory.
We recommend to always add a setter for such types.
If you initialize a collection, make sure it is not immutable (as in the preceding example).
* If nested POJO properties are initialized (like the `Security` field in the preceding example), a setter is not required.
If you want the binder to create the instance on the fly by using its default constructor, you need a setter.
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.
In this setup, the `@ConstructorBinding` annotation is used to indicate that constructor binding should be used.
This means that the binder will expect to find a constructor with the parameters that you wish to have bound.
Nested members of a `@ConstructorBinding` class (such as `Security` in the example above) will also be bound via their constructor.
Default values can be specified using `@DefaultValue` and the same conversion service will be applied to coerce the `String` value to the target type of a missing property.
If you wish you return a non-null instance of `Security` even when no properties are bound to it, you can use an empty `@DefaultValue` annotation to do so:
NOTE: To use constructor binding the class must be enabled using `@EnableConfigurationProperties` or configuration property scanning.
You cannot use constructor binding with beans that are created by the regular Spring mechanisms (e.g. `@Component` beans, beans created via `@Bean` methods or beans loaded using `@Import`)
TIP: If you have more than one constructor for your class you can also use `@ConstructorBinding` directly on the constructor that should be bound.
NOTE: The use of `java.util.Optional` with `@ConfigurationProperties` is not recommended as it is primarily intended for use as a return type.
As such, it is not well-suited to configuration property injection.
For consistency with properties of other types, if you do declare an `Optional` property and it has no value, `null` rather than an empty `Optional` will be bound.
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.
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:
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:
When the `@ConfigurationProperties` bean is registered using configuration property scanning or via `@EnableConfigurationProperties`, the bean has a conventional name: `<prefix>-<fqn>`, where `<prefix>` is the environment key prefix specified in the `@ConfigurationProperties` annotation and `<fqn>` is 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.
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.
Any JavaBean property defined with the `another` prefix is mapped onto that `AnotherComponent` bean in manner similar to the preceding `SomeProperties` example.
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`).
As an example, consider the following `@ConfigurationProperties` class:
| Standard list syntax using `[ ]` or comma-separated values
| 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 <<features#features.external-config.typesafe-configuration-properties.relaxed-binding.environment-variables>>).
| Numeric values surrounded by underscores (see <<features#features.external-config.typesafe-configuration-properties.relaxed-binding.environment-variables>>)
| System properties
| Camel case, kebab case, or underscore notation
| Standard list syntax using `[ ]` or comma-separated values
NOTE: For YAML files, the brackets need to be surrounded by quotes for the keys to be parsed properly.
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 wasn't surrounded by square brackets.
You may also occasionally need to use the bracket notation if your `key` contains a `.` and you are binding to non-scalar value.
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"}`.
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`).
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`).
NOTE: The preceding merging rules apply to properties from all property sources, and not just files.
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`).
NOTE: 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 is not required for configuration keys coercion and only rely on custom converters qualified with `@ConfigurationPropertiesBinding`.
Spring Boot attempts to validate `@ConfigurationProperties` classes whenever they are annotated with Spring's `@Validated` annotation.
You can use JSR-303 `javax.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:
TIP: You can also trigger validation by annotating the `@Bean` method that creates the configuration properties with `@Validated`.
To ensure that validation is always triggered for nested properties, even when no properties are found, the associated field must be annotated with `@Valid`.
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.
TIP: The `spring-boot-actuator` module includes an endpoint that exposes all `@ConfigurationProperties` beans.
Point your web browser to `/actuator/configprops` or use the equivalent JMX endpoint.
See the "<<actuator#actuator.endpoints, Production ready features>>" section for details.
NOTE: If you do want to use `@Value`, we recommend that you refer to property names 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 `@ConfigurationProperties`.
For example, `@Value("{demo.item-price}")` will pick up `demo.item-price` and `demo.itemPrice` forms from the `application.properties` file, as well as `DEMO_ITEMPRICE` from the system environment.
If you used `@Value("{demo.itemPrice}")` instead, `demo.item-price` and `DEMO_ITEMPRICE` would not be considered.
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.
`SpEL` expressions from <<features#features.external-config.files,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 via `@Value`.