Skip to content

Application configuration

Spring offers an auto-configuration mechanism, but it is also possible to customize the form of existing beans to the needs of the application and create your own configuration properties. This chapter describes these methods.

application.properties file

When creating a [base] (spring_boot_basics.md#project-creating) project, in the resources directory we will find a file named application.properties. This file is used to configure the application with certain properties that we can assign values to.

The keys are available in the application.properties file and they depend on the dependencies used (i.e. the dependencies section in the pox.xml file). They allow you to customize the bean or pass a certain property to the application. The most frequently available keys can be found in the documentation of a given project (e.g. starter).

Properties in the application.properties file are written according to the following rules:

  • individual words are separated by dots and written in lower case letters
  • if a certain subgroup of properties consists of many words, we use the kebab-case convention
  • the key is separated from the value by the sign =
  • if the key starts with spring, it is usually a configuration property of the official launchpad

An example of a key using these conventions: spring.datasource.hikari.jdbc-url.

NOTE: If you are using the IntelliJ Ultimate IDE, the available keys should be prompted for filling the application.properties file.

NOTE: The application.properties file may also have a so-called YAML format. In this case, the file is named application.yml. In this section, however, all the examples show the contents of the application.properties file.

Sample properties

If the project uses the spring-boot-starter-web starter, we have access to the following properties:

  • server.port - indicates the port on which Tomcat will be run, eg server.port=8081
  • spring.jackson.default-property-inclusion - defines whether a bean that is an object of the ObjectMapper type, i.e. an object responsible for serialization and deserialization of objects (JSON<->Java) will include specific keys in the output, e.g. for the value ofnon_null, non-null keys '
  • spring.jackson.property-naming-strategy - defines the field convention used during serialization and deserialization of objects with an object of type ObjectMapper (e.g.snake_case)

Environment Variables

When delivering the finished application to the client (or e.g. the docker image to the dev-ops), it must be possible to overwrite the values used in the application.properties file. We can do this using the so-called relaxed binding mechanism. Thanks to it, each key can be replaced with an environment variable in which each letter is uppercase and the period is replaced with the character _, e.g.

application.properties Environment Variable
server.port SERVER_PORT
spring.h2.console.path SPRING_H2_CONSOLE_PATH

Property injection

Spring also allows you to inject your own application-specific properties. This is done with the @Value annotation. The key placed inside the annotation should meet the same conditions as those described [above] (# applicationproperties-file). Such properties can be injected directly into the class field or using the constructor of a class that is in context.

The used key should be preceded by the $ character inside the braces, i.e. the { and } characters, while after the : character it is possible to specify a default value in case it is not given by the programmer or the user (in otherwise, the application will not run properly).

The next example shows the use of the @Value annotation. In it, we inject the value directly into the field:

import org.springframework.stereotype.Component;

@Component
public class AnotherBean {
}
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class SomeBean {

  @Value("${pl.sdacademy.example}")
  private String injectedValue;

  private final AnotherBean anotherBean;

  public SomeBean(final AnotherBean anotherBean) {
    this.anotherBean = anotherBean;
  }
  // remaining methods

}

// in the file application.properties:
// pl.sdacademy.example=hi

Another piece of code injects the property using a constructor and defines the default value:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class SomeBean {

  private final String injectedValue;
  private final AnotherBean anotherBean;

  public SomeBean(final AnotherBean anotherBean,
                  @Value("${pl.sdacademy.example:default_value}") final String injectedValue) {
    this.anotherBean = anotherBean;
    this.injectedValue = injectedValue;
  }

  public String getInjectedValue() {
    return injectedValue;
  }
}

NOTE: The value for the key in the @Value annotation may be specified in the application.properties file.

Grouping of injected properties

In case when we want to inject many properties into the application, we can do it by using the @Value annotation many times. However, it is a better idea to use the @ConfigurationProperties annotation. We use this annotation over a class that represents a group of properties (it is usually closely related). It requires us to provide a common prefix for all fields. In addition, to be visible in the context of an application, this class should define getters and setters and be used with one of the annotations:

  • @Component
  • @EnableConfigurationProperties(KlasaZWłaściwościmi.class) - this annotation may be given elsewhere in the application

Such defined properties can be specified in the application.properties file or by means of environment-variables.

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;


@Component // or //@EnableConfigurationProperties(PropertiesGroup.class)
@ConfigurationProperties(prefix = "pl.sdacademy.group")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PropertiesGroup {
  private String propA;
  private Integer propB;
}

/* in the application.properties file
pl.sdacademy.group.prop-a=prop_A_value
pl.sdacademy.group.prop-b=17
*/

Classes marked with the annotation @ConfigurationProperties may also contain [collections] (../javaAdvanced/collections.md). In this case:

  • for lists, we use an array entry at the end of the property name - an index inside the [ and ] characters
  • for maps, after the full name of the property we put the . sign, and then we give the name of the key to which we assign the value

E.g:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "sda.collections")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ConfigurationWithCollections {

  private List<String> usernames;
  private Map<String, Integer> values;
}

An example of the content of the application.properties file, which assigns certain values to the above-defined fields:

sda.collections.usernames[0]=user1
sda.collections.usernames[1]=user2
sda.collections.values.key1=1
sda.collections.values.key2=2