Spring Boot Externalizing Configuration


Externalizing configuration properties

Spring Boot is developer-friendly and supports a number of features to increase productivity. One of them is externalizing configuration properties. Externalizing configuration properties means that all the configuration values are not hardcoded in the application and hence we can change the values as needed while deploying the application. Spring Boot supports a number of different ways to externalize properties and read them in the application.
We can have properties defined in various locations( different property files ) and various sources (property files, command line, System Properties, etc.), spring boot uses a specific order to read the values from those sources, which also enables us to override values. For example, we may provide some default values to the application, then while running it we might want to override some values.
The following are some of the places from where the application can read property values. The list is in descending priority. For example, property values passed though command-line argument will override Java system properties or default properties.
Property value priority order (Descending priority)
  • Command-line arguments.
  • Java System properties.
  • OS level environment variables.
  • @PropertySource annotations classes.
  • Application properties outside of your packaged jar.
  • Application properties packaged inside your jar.
  • Default properties.

Accessing properties values

Spring Boot provides multiple ways to access property values. The following are some of the ways. We will be using the bellow property file (office-address.properties) to demonstrate some of the ways to access the values defined in it.
office-address.properties
Property file which contains properties names and values. We will read this property to java classes by using @Value and @ConfigurationProperties
#Sample Property file
contact.from=admin
contact.fromEmail=admin@bootng.com
contact.fromPhone=Hello from bootng
contact.fromTwitter=@BootNGTweet

address.street=1901 Palo Alto Avenue
address.city=Palo Alto
address.state=California
address.zip=950441

Reading with @Value annotation

@Value
With @Value annotation, we can map a particular property to a java class field. Here we mapped different fields of the class AddressProperties to the properties in the office-address.properties by individual @Value annotations.
@Component
@PropertySource("classpath:office-address.properties")
@Validated
public class AddressProperties {
  @Value("${address.street}")
  private String street;

  @Value("${address.city}")
  private String city;

  @Value("${address.state}")
  private String state;

  @NotNull
  @Value("${address.zip}")
  private String zip;
}

Reading with @ConfigurationProperties annotation

@ConfigurationProperties
@Value is good when the properties are small in number. But say we want many properties to individual fields in the Java Class then we can use ConfigurationProperties. Spring will map the field name with the property name and will populate the value automatically. In the bellow example the filename twitterHandle does not match with the property fromTwitter. So with @ConfigurationProperties Spring boot will not be able to match the field with corresponding property and hence it would be null. To fix the issue we can use @Value("${contact.fromTwitter}") for the twitter field to populate it with @Value annotation.
@Component
@ConfigurationProperties(prefix = "contact")
@PropertySource("classpath:office-address.properties")
public class ContactProperties {

  private String from;

  private String fromEmail;

  @Value("${contact.fromTwitter}")
  private String twitterHandle;

  public String getFrom() {
    return from;
  }

}

Validating properties

@Validated Annotation
@Validated Annotation can be used to validate the field values. Spring Boot supports many validation rules, like NotNull, Email, NotEmpty, etc. Similar to the above class but now we have decorated the class with @Validated annotation and marked some of the fields with @NotNull and @Email validations. Doing so, if the values for these fields do not comfort to the validation rules defined, Spring Boot will throw expectation.
@Component
@ConfigurationProperties(prefix = "contact")
@PropertySource("classpath:office-address.properties")
@Validated
public class ContactProperties {

  @NotNull
  private String from;

  @Email
  private String fromEmail;

  @Value("${contact.fromTwitter}")
  private String twitterHandle;

  public String getFrom() {
    return from;
  }
}
Summary
  • We can use @Value annotation to map individual properties from the property file.
  • We can use @ConfigurationProperties to map all the fields of a class with respective properties from the property file.
  • With @ConfigurationProperties the field name in the class and property name should match.
  • With @ConfigurationProperties the prefix if provided is used to filter properties with matching name.
  • We can use both @Value and @ConfigurationProperties in the same class.
  • We can also validate the field values along with populating using @Validated annotation.

No comments :

Post a Comment

Please leave your message queries or suggetions.