Spring Boot @ConfigurationProperties
Spring Boot provides a very neat way to load properties for an application. Consider a set of properties described using YAML format:
prefix:
stringProp1: propValue1
stringProp2: propValue2
intProp1: 10
listProp:
- listValue1
- listValue2
mapProp:
key1: mapValue1
key2: mapValue2
These entries can also be described in a traditional application.properties file the following way:
prefix.stringProp1=propValue1
prefix.stringProp2=propValue2
prefix.intProp1=10
prefix.listProp[0]=listValue1
prefix.listProp[1]=listValue2
prefix.mapProp.key1=mapValue1
prefix.mapProp.key2=mapValue2
It has taken me a little while, but I do like the hierarchical look of the properties described in a YAML format. To indept on this visit Spring boot training
So now, given this property file, a traditional Spring application would have loaded up the properties in the following way:
public class SamplePropertyLoadingTest {
@Value("${prefix.stringProp1}")
private String stringProp1;
Note the placeholder for "prefix.stringProp" key.
This however is not ideal for loading a family of related properties, say in this specific case namespaced by the prefix conveniently named "prefix".
The approach Spring boot takes is to define a bean that can hold all the families of related properties this way: And for more clarification Spring boot online course
@ConfigurationProperties(prefix = "prefix")
@Component
public class SampleProperty {
private String stringProp1;
private String stringProp2;
@Max(99)
@Min(0)
private Integer intProp1;
private List<String> listProp;
private Map<String, String> mapProp;
...
}
At runtime, all the fields would be bound to the related properties cleanly.
Additionally note the JSR-303 annotations on top of the "intProp1" field that validates that the value of the field is between 0 and 99. @ConfigurationProperties will call the validator to ensure that the bound bean is validated.
An integration test using this feature is shown here:
package prop;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleWebApplication.class)
public class SamplePropertyLoadingTest {
@Autowired
private SampleProperty sampleProperty;
@Value("${prefix.stringProp1}")
private String stringProp1;
@Test
public void testLoadingOfProperties() {
System.out.println("stringProp1 = " + stringProp1);
assertThat(sampleProperty.getStringProp1(), equalTo("propValue1"));
assertThat(sampleProperty.getStringProp2(), equalTo("propValue2"));
assertThat(sampleProperty.getIntProp1(), equalTo(10));
assertThat(sampleProperty.getListProp(), hasItems("listValue1", "listValue2"));
assertThat(sampleProperty.getMapProp(), allOf(hasEntry("key1", "mapValue1"),
hasEntry("key2", "mapValue2")));
}
}
If you are interested in exploring this sample further, Go through Spring Boot Online Training.