# Properties with Spring and Spring Boot

### **1. Overview** <a href="#bd-overview" id="bd-overview"></a>

This tutorial will show **how to set up and use properties in Spring** via Java configuration and *@PropertySource.*

**We’ll also see how properties work in Spring Boot.**

### **2. Register a Properties File via Annotations** <a href="#bd-java" id="bd-java"></a>

Spring 3.1 also introduces **the new&#x20;*****@PropertySource*****&#x20;annotation** as a convenient mechanism for adding property sources to the environment.

We can use this annotation in conjunction with the *@Configuration* annotation:

```
@Configuration
@PropertySource("classpath:foo.properties")
public class PropertiesWithJavaConfig {
    //...
}
```

Another very useful way to register a new properties file is using a placeholder, which allows us to **dynamically select the right file at runtime**:

```
@PropertySource({ 
  "classpath:persistence-${envTarget:mysql}.properties"
})
...
```

#### 2.1. Defining Multiple Property Locations <a href="#bd-1-defining-multiple-property-locations" id="bd-1-defining-multiple-property-locations"></a>

The *@PropertySource* annotation is repeatable [according to Java 8 conventions](https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html). Therefore, if we’re using Java 8 or higher, we can use this annotation to define multiple property locations:

```
@PropertySource("classpath:foo.properties")
@PropertySource("classpath:bar.properties")
public class PropertiesWithJavaConfig {
    //...
}
```

Of course, **we can also use the&#x20;*****@PropertySources*****&#x20;annotation and specify an array of&#x20;*****@PropertySource*****.** This works in any supported Java version, not just in Java 8 or higher:

```
@PropertySources({
    @PropertySource("classpath:foo.properties"),
    @PropertySource("classpath:bar.properties")
})
public class PropertiesWithJavaConfig {
    //...
}
```

In either case, it’s worth noting that in the event of a property name collision, the last source read takes precedence.

### **3. Using/Injecting Properties** <a href="#bd-usage" id="bd-usage"></a>

**Injecting a property with the&#x20;*****@Value*****&#x20;annotation** is straightforward:

```
@Value( "${jdbc.url}" )
private String jdbcUrl;
```

**We can also specify a default value for the property:**

```
@Value( "${jdbc.url:aDefaultUrl}" )
private String jdbcUrl;
```

The new *PropertySourcesPlaceholderConfigurer* added in Spring 3.1 **resolve ${…} placeholders within bean definition property values and&#x20;*****@Value*****&#x20;annotations**.

Finally, we can **obtain the value of a property using the&#x20;*****Environment*****&#x20;API**:

```
@Autowired
private Environment env;
...
dataSource.setUrl(env.getProperty("jdbc.url"));
```

Before we go into more advanced configuration options for properties, let’s spend some time looking at the new properties support in Spring Boot.

Generally speaking, **this new support involves less configuration compared to standard Spring**, which is of course one of the main goals of Boot.

#### **4.1.&#x20;*****application.properties:*****&#x20;the Default Property File** <a href="#bd-1-applicationproperties-the-default-property-file" id="bd-1-applicationproperties-the-default-property-file"></a>

Boot applies its typical convention over configuration approach to property files. This means that **we can simply put an&#x20;*****application.properties*****&#x20;file in our&#x20;*****src/main/resources*****&#x20;directory, and it will be auto-detected**. We can then inject any loaded properties from it as normal.

So, by using this default file, we don’t have to explicitly register a *PropertySource* or even provide a path to a property file.

We can also configure a different file at runtime if we need to, using an environment property:

```
java -jar app.jar --spring.config.location=classpath:/another-location.properties
```

As of [Spring Boot 2.3](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#support-of-wildcard-locations-for-configuration-files), **we can also specify wildcard locations for configuration files**.

For example, we can set the *spring.config.location* property to *config/\*/*:

```
java -jar app.jar --spring.config.location=config/*/
```

This way, Spring Boot will look for configuration files matching the *config/\*/* directory pattern outside of our jar file. This comes in handy when we have multiple sources of configuration properties.

Since version *2.4.0*, **Spring Boot supports using multi-document properties files**, similarly [as YAML does](https://yaml.org/spec/1.2/spec.html#id2760395) by design:

```
baeldung.customProperty=defaultValue
#---
baeldung.customProperty=overriddenValue
```

Note that for properties files, the three-dashes notation is preceded by a comment character (*#*).

#### **4.2. Environment-Specific Properties File** <a href="#bd-2-environment-specific-properties-file" id="bd-2-environment-specific-properties-file"></a>

If we need to target different environments, there’s a built-in mechanism for that in Boot.

**We can simply define an&#x20;*****application-environment.properties*****&#x20;file in the&#x20;*****src/main/resources*****&#x20;directory, and then set a Spring profile with the same environment name.**

For example, if we define a “staging” environment, that means we’ll have to define a *staging* profile and then *application-staging.properties*.

This env file will be loaded and **will take precedence over the default property file.** Note that the default file will still be loaded, it’s just that when there is a property collision, the environment-specific property file takes precedence.

#### **4.3. Test-Specific Properties File** <a href="#bd-3-test-specific-properties-file" id="bd-3-test-specific-properties-file"></a>

We might also have a requirement to use different property values when our application is under test.

**Spring Boot handles this for us by looking in our&#x20;*****src/test/resources*****&#x20;directory during a test run**. Again, default properties will still be injectable as normal but will be overridden by these if there is a collision.

#### **4.4. The&#x20;*****@TestPropertySource*****&#x20;Annotation** <a href="#bd-4-the-testpropertysource-annotation" id="bd-4-the-testpropertysource-annotation"></a>

If we need more granular control over test properties, then we can use the [*@TestPropertySource*](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/context/TestPropertySource.html) annotation.

**This allows us to set test properties for a specific test context, taking precedence over the default property sources:**

```
@RunWith(SpringRunner.class)
@TestPropertySource("/foo.properties")
public class FilePropertyInjectionUnitTest {

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

    @Test
    public void whenFilePropertyProvided_thenProperlyInjected() {
        assertThat(foo).isEqualTo("bar");
    }
}
```

If we don’t want to use a file, we can specify names and values directly:

```
@RunWith(SpringRunner.class)
@TestPropertySource(properties = {"foo=bar"})
public class PropertyInjectionUnitTest {

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

    @Test
    public void whenPropertyProvided_thenProperlyInjected() {
        assertThat(foo).isEqualTo("bar");
    }
}
```

**We can also achieve a similar effect using the&#x20;*****properties*****&#x20;argument of the** [***@SpringBootTest***](http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/context/SpringBootTest.html) **annotation:**

```
@RunWith(SpringRunner.class)
@SpringBootTest(
  properties = {"foo=bar"}, classes = SpringBootPropertiesTestApplication.class)
public class SpringBootPropertyInjectionIntegrationTest {

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

    @Test
    public void whenSpringBootPropertyProvided_thenProperlyInjected() {
        assertThat(foo).isEqualTo("bar");
    }
}
```

#### **4.5. Hierarchical Properties** <a href="#bd-5-hierarchical-properties" id="bd-5-hierarchical-properties"></a>

If we have properties that are grouped together, we can make use of the [*@ConfigurationProperties*](http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/context/properties/ConfigurationProperties.html) annotation, which will map these property hierarchies into Java objects graphs.

Let’s take some properties used to configure a database connection:

```
database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar
```

And then let’s use the annotation to map them to a database object:

```
@ConfigurationProperties(prefix = "database")
public class Database {
    String url;
    String username;
    String password;

    // standard getters and setters
}
```

Spring Boot applies it’s convention over configuration approach again, automatically mapping between property names and their corresponding fields. All that we need to supply is the property prefix.

If you want to dig deeper into configuration properties, have a look at our in-depth article.

#### **4.6. Alternative: YAML Files** <a href="#bd-6-alternative-yaml-files" id="bd-6-alternative-yaml-files"></a>

Spring also supports YAML files.

All the same naming rules apply for test-specific, environment-specific, and default property files. The only difference is the file extension and a dependency on the [SnakeYAML](https://bitbucket.org/snakeyaml/snakeyaml/src) library being on our classpath.

**YAML is particularly good for hierarchical property storage**; the following property file:

```
database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar
secret: foo
```

is synonymous with the following YAML file:

```
database:
  url: jdbc:postgresql:/localhost:5432/instance
  username: foo
  password: bar
secret: foo
```

It’s also worth mentioning that YAML files do not support the *@PropertySource* annotation, so if we need to use this annotation, it would constrain us to using a properties file.

Another remarkable point is that in version 2.4.0 Spring Boot changed the way in which properties are loaded from multi-document YAML files. Previously, the order in which they were added was based on the profile activation order. With the new version, however, the framework follows the same ordering rules that we indicated earlier for *.properties* files; properties declared lower in the file will simply override those higher up.

Additionally, in this version profiles can no longer be activated from profile-specific documents, making the outcome clearer and more predictable.

#### **4.7. Importing Additional Configuration Files** <a href="#bd-7-importing-additional-configuration-files" id="bd-7-importing-additional-configuration-files"></a>

Prior to version 2.4.0, Spring Boot allowed including additional configuration files using the *spring.config.location* and *spring.config.additional-location* properties, but they had certain limitations. For instance, they had to be defined before starting the application (as environment or system properties, or using command-line arguments) as they were used early in the process.

In the mentioned version, **we can use the&#x20;*****spring.config.import*****&#x20;property within the&#x20;*****application.properties*****&#x20;or&#x20;*****application.yml*****&#x20;file to easily include additional files.** This property supports some interesting features:

* adding several files or directories
* the files can be loaded either from the classpath or from an external directory
* indicating if the startup process should fail if a file is not found, or if it’s an optional file
* importing extensionless files

Let’s see a valid example:

```
spring.config.import=classpath:additional-application.properties,
  classpath:additional-application[.yml],
  optional:file:./external.properties,
  classpath:additional-application-properties/
```

Note: here we formatted this property using line breaks just for clarity.

Spring will treat imports as a new document inserted immediately below the import declaration.

#### **4.8. Properties From Command Line Arguments** <a href="#bd-8-properties-from-command-line-arguments" id="bd-8-properties-from-command-line-arguments"></a>

Besides using files, we can pass properties directly on the command line:

```
java -jar app.jar --property="value"
```

We can also do this via system properties, which are provided before the *-jar* command rather than after it:

```
java -Dproperty.name="value" -jar app.jar
```

#### **4.9. Properties From Environment Variables** <a href="#bd-9-properties-from-environment-variables" id="bd-9-properties-from-environment-variables"></a>

Spring Boot will also detect environment variables, treating them as properties:

```
export name=value
java -jar app.jar
```

#### **4.10. Randomization of Property Values** <a href="#bd-10-randomization-of-property-values" id="bd-10-randomization-of-property-values"></a>

If we don’t want determinist property values, we can use [*RandomValuePropertySource*](https://docs.spring.io/spring-boot/docs/1.5.7.RELEASE/api/org/springframework/boot/context/config/RandomValuePropertySource.html) to randomize the values of properties:

```
random.number=${random.int}
random.long=${random.long}
random.uuid=${random.uuid}
```

#### **4.11. Additional Types of Property Sources** <a href="#bd-11-additional-types-of-property-sources" id="bd-11-additional-types-of-property-sources"></a>

Spring Boot supports a multitude of property sources, implementing a well-thought-out ordering to allow sensible overriding. It’s worth consulting the [official documentation](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html), which goes further than the scope of this article.

### **5. Configuration Using Raw Beans — the&#x20;*****PropertySourcesPlaceholderConfigurer*** <a href="#bd-raw3_1" id="bd-raw3_1"></a>

Besides the convenient methods of getting properties into Spring, we can also define and regiter the property configuration bean manually.

**Working with the&#x20;*****PropertySourcesPlaceholderConfigurer*****&#x20;gives us full control over the configuration, with the downside of being more verbose and most of the time, unnecessary.**

Let’s see how we can define this bean using Java configuration:

```
@Bean
public static PropertySourcesPlaceholderConfigurer properties(){
    PropertySourcesPlaceholderConfigurer pspc
      = new PropertySourcesPlaceholderConfigurer();
    Resource[] resources = new ClassPathResource[ ]
      { new ClassPathResource( "foo.properties" ) };
    pspc.setLocations( resources );
    pspc.setIgnoreUnresolvablePlaceholders( true );
    return pspc;
}
```

### **6. Properties in Parent-Child Contexts** <a href="#bd-parent-child" id="bd-parent-child"></a>

This question comes up again and again: What happens when our **web application has a parent and a child context**? The parent context may have some common core functionality and beans, and then one (or multiple) child contexts, maybe containing servlet-specific beans.

In that case, what’s the best way to define properties files and include them in these contexts? And how to best retrieve these properties from Spring?

We’ll give a simple breakdown.

If the file is **defined in the Parent context**:

* *@Value* works in **Child context**: YES
* *@Value* works in **Parent context**: YES
* *environment.getProperty* in **Child context**: YES
* *environment.getProperty* in **Parent context**: YES

If the file is **defined in the Child context**:

* *@Value* works in **Child context**: YES
* *@Value* works in **Parent context**: NO
* *environment.getProperty* in **Child context**: YES
* *environment.getProperty* in **Parent context**: NO

### **7. Conclusion** <a href="#bd-conclusion" id="bd-conclusion"></a>

This article showed several examples of working with properties and properties files in Spring.

As always, the entire code backing the article is available [over on GitHub](https://github.com/eugenp/tutorials/tree/master/spring-boot-modules/spring-boot-properties).

{% embed url="<https://www.baeldung.com/properties-with-spring>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jihoony.gitbook.io/developers-notes/developer/readme/spring/properties-with-spring-and-spring-boot.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
