Managing complex application properties with Spring Boot

Spring boot supports dynamic configurations through application properties. A fluid and configurable application is easier to manage in production owing to changing needs, where otherwise a wait till another deployment can be avoided.

let us explore some of the complex ways to pass and consume configuration properties through spring boot.

Photo credit – Leonel Fernandez @ unsplash.com

@Value Annotation :

To consume basic types spring provides @Value annotation. It is as simple as adding properties to application.yaml or application.properties and consuming via @Value annotation inside any spring component.

### application.yml

basic-value: basic value
nested-value-sample:
 name: Luffy
 age: 19
 is-pirate: true

To access a property, the property’s key is added with $ sign and surrounded by curly braces. If needed optionally default values can be added with a colon after the key.

@Service
public class BasicProperties {
	
	@Value("${basic-value}")
	private String basicValue;
	
	@Value("${nested-value-sample.name}")
	private String name;
	
	@Value("${nested-value-sample.age}")
	private int age;
	
	@Value("${nested-value-sample.is-pirate: false}")
	private boolean isPirate;
// ... //

@ConfigurationProperties

@Value is fine for basic values being passed, but for complex properties Spring provides the annotation @ConfigurationProperties.

Plain Old Java Object
Array of String/Integers
A Map of Objects
Nested Objects

Plain Old Java Object

Add a set of properties under a root property key in application.yaml

## application.yaml

complex-properties:
 total-slots: 220
 max-age: 55

Instead of access individual properties using @value , a POJO can be created with @ConfigurationProperties linking to the root key in application.yaml.

@Component
@ConfigurationProperties("complex-properties")
@Data
public class ComplexProperties {

	private String totalSlots;
	private int maxAge;

//** **//

Now, this POJO containing configuration properties can be access with @autowired

@Autowired 
ComplexProperties complexProperties;

Array

List or Array of Objects can be loaded too

public class ComplexProperties {

//** **//

private ArrayList<String> countries;

private ArrayList<Integer> years;

In application.yml array of objects can be passed as a comma separated value or as a yaml array

### application.yaml

complex-properties:
 countries:
 - USA
 - India
 - UAE
 - China
 years: 2015,2016,2020

Map

Map of Objects

public class ComplexProperties {
//** **//
	private Map<String, Boolean> allowedProfessions;
	private Map<String, Integer> availableSlots;

In application.yaml map can be either passed as a key and value pairs under a root key or yaml map object

### application.yaml

complex-properties: 
 allowed-professions:
 doctor: true
 engineer: true
 pilot: false
 available-slots: { USA: 100, India: 50, China: 70 }

Nested Objects

A POJO can hold any number of nested POJO and other objects making it possible to load a wide variety of flexible configurations being loaded through application.yaml.

### Application.yaml

nested-complex-properties:
 hero:
 name: Captain America
 age: 27
 skills:
 - agility
 - strength
 - speed
 - endurance

to load nested configurations

@Component
@ConfigurationProperties("nested-complex-properties")
@Data
public class NestedProperties {
	private Hero hero;
}

Happy coding !!

Source Code:

https://github.com/gladius/complex-application-properties-spring-boot