[ad_1]
Do you additionally get misplaced within the configuration annotations of Spring Boot and the right way to use them? On this weblog, you’ll check out the configuration annotations, what they imply, and the way you’ll be able to observe them to your code — the whole lot is defined by way of examples. Revel in!
Advent
The annotations containing the phrase configuration in Spring Boot can also be overwhelming. You have got @Configuration
, @EnableConfigurationProperties
, @ConfigurationPropertiesScan
, and many others. However what do they in fact do, and the way do you wish to have to use them to your code?
A excellent place to begin for making use of best possible practices can also be discovered within the reliable Spring Boot documentation (seek for configuration). On the other hand, it lacks transparent examples, individually. That’s the objective of this weblog: give an explanation for the other choices, give an explanation for the variations, and display how they are able to be used by way of examples.
The supply code used on this weblog can also be discovered on GitHub.
Pattern Utility
The pattern software is created with get started.spring.io and uses the Spring Internet and Lombok dependencies.
This segment provides an outline of ways the repository and the elemental software are arrange. Main points will likely be made transparent within the sections hereafter.
The homes are positioned within the MyProperties
elegance and consist out of:
- a boolean
enabled
; - a string
stringConfig
; - a nested
further
configuration merchandise consisting of:- a boolean
addEnabled
; - a string
addString
.
- a boolean
The boolean values comprise their default worth, and the string values will likely be given a worth within the software.homes
record. The price of the addString
assets can even comprise a connection with the stringConfig
assets. This fashion, you’ll be able to mix assets values.
my.homes.string-config=First piece
my.homes.further.add-string=${my.homes.string-config} 2d piece
One ConfigurationController
is added, which reads the configuration homes and returns them.
@RequestMapping("/configuration")
public String configuration() {
StringBuilder outcome = new StringBuilder();
outcome.append("Worth of enabled = ").append(myProperties.isEnabled()).append("n");
outcome.append("Worth of stringConfig = ").append(myProperties.getStringConfig()).append("n");
if (myProperties.getAdditional() != null) {
outcome.append("Worth of extra.addEnabled = ").append(myProperties.getAdditional().isAddEnabled()).append("n");
outcome.append("Worth of extra.addString = ").append(myProperties.getAdditional().getAddString()).append("n");
}
go back outcome.toString();
}
The applying is composed of a number of modules. Every module corresponds to another matter lined on this weblog.
Construct the applying:
Navigate to the listing of a module and run the applying:
The endpoint can also be invoked as follows:
$ curl http://localhost:8080/configuration
Every module accommodates 3 assessments:
HttpRequestIT
: This examine will get started a whole server the use of the@SpringBootTest
annotation;WebLayerIT
: This examine begins an software context with a restricted collection of beans the use of the@WebMvcTest
annotation;WebLayerTestPropertiesIT
: similar toWebLayerIT
, however this time, particular software homes are used.
@ConfigurationProperties + @Part
In module config1, you’ll map the homes to config elegance MyProperties
by way of the @ConfigurationProperties
annotation. In an effort to use it within the controller, you additionally upload the @Part
annotation. Additionally notice that setters and getters wish to be to be had within the MyProperties
elegance, those are generated by way of the @Getter
and @Setter
Lombok annotations.
The MyProperties
elegance is the next:
@Getter
@Setter
@Part
@ConfigurationProperties("my.homes")
public elegance MyProperties {
personal boolean enabled;
personal String stringConfig;
personal ultimate Further further = new Further();
@Getter
@Setter
public static elegance Further {
personal boolean addEnabled;
personal String addString;
}
}
Within the controller, you simply wish to inject the MyProperties
element.
@RestController
public elegance ConfigurationController {
personal ultimate MyProperties myProperties;
@Autowired
public ConfigurationController(MyProperties myProperties) {
this.myProperties = myProperties;
}
...
}
The assessments do not have any particular annotations on this case.
Complete Spring Server Check
This examine (HttpRequestIT
) is annotated with @SpringBootTest
and it’s ensured {that a} random port is getting used to be able to save you port conflicts when operating the examine. The endpoint is named, and the reaction is validated. No further annotations are wanted to be able to use the homes.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public elegance HttpRequestIT {
@Worth(worth="${native.server.port}")
personal int port;
@Autowired
personal TestRestTemplate restTemplate;
@Check
public void configurationShouldReturnProperties() throws Exception {
assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/configuration",
String.elegance)).accommodates("""
Worth of enabled = false
Worth of stringConfig = First piece
Worth of extra.addEnabled = false
Worth of extra.addString = First piece 2d piece""");
}
}
Spring Utility Context With out Server Check
This examine (WebLayerIT
) is annotated with @WebMvcTest
which means that this examine begins an software context with a restricted collection of beans. Due to this fact, you wish to have so as to add the @EnableConfigurationProperties
annotation to be able to use the homes. @EnableConfigurationProperties
creates a binding between a configuration elegance and the examine.
@WebMvcTest
@EnableConfigurationProperties(MyProperties.elegance)
public elegance WebLayerIT {
@Autowired
personal MockMvc mockMvc;
@Check
public void configurationShouldReturnProperties() throws Exception {
this.mockMvc.carry out(get("/configuration")).andDo(print()).andExpect(standing().isOk())
.andExpect(content material().string(containsString("""
Worth of enabled = false
Worth of stringConfig = First piece
Worth of extra.addEnabled = false
Worth of extra.addString = First piece 2d piece""")));
}
}
Check Utility Houses
The above assessments use the applying homes as outlined to your software. For examine functions, it’s ceaselessly wanted to make use of test-specific software homes. Those can also be put within the assessments listing. In an effort to use them, you need to use the @TestPropertyResource
annotation. The examine WebLayerTestPropertiesIT
is similar to the above WebLayerIT
, but even so that, it makes use of the examine software homes.
@WebMvcTest
@EnableConfigurationProperties(MyProperties.elegance)
@TestPropertySource(places = "/application-test.homes")
public elegance WebLayerTestPropertiesIT {
@Autowired
personal MockMvc mockMvc;
@Check
public void configurationShouldReturnProperties() throws Exception {
this.mockMvc.carry out(get("/configuration")).andDo(print()).andExpect(standing().isOk())
.andExpect(content material().string(containsString("""
Worth of enabled = false
Worth of stringConfig = First examine piece
Worth of extra.addEnabled = false
Worth of extra.addString = First examine piece 2d piece""")));
}
}
@ConfigurationProperties + @EnableConfigurationProperties
In module config2, you’ll use once more the @ConfigurationProperties
, identical to in module config1, however this time with out the @Part
annotation. In an effort to use the homes within the controller, you wish to have so as to add the @EnableConfigurationProperties
annotation.
The MyProperties
elegance with out the @Part
annotation:
@Getter
@Setter
@ConfigurationProperties("my.homes")
public elegance MyProperties {
...
}
The controller with the @EnableConfigurationProperties
annotation:
@RestController
@EnableConfigurationProperties(MyProperties.elegance)
public elegance ConfigurationController {
personal ultimate MyProperties myProperties;
@Autowired
public ConfigurationController(MyProperties myProperties) {
this.myProperties = myProperties;
}
...
}
It isn’t essential so as to add the @EnableConfigurationProperties
annotation within the assessments as a result of this annotation is already added to the controller.
@ConfigurationProperties + @Part
In module config3, you’ll use the similar setup as in module config1, however this time with the @Configuration
annotation. The @Configuration
annotation creates a Spring bean of configuration stereotype. The @EnableConfigurationProperties
annotation must now not be used immediately at the side of the @Configuration
annotation, see additionally this Stack Overflow solution of Andy Wilkinson.
The MyProperties
elegance is similar to the considered one of module config2:
@Getter
@Setter
@ConfigurationProperties("my.homes")
public elegance MyProperties {
...
}
You introduce a brand new elegance ApplicationConfig
that may act as a configuration bean. You annotate it, due to this fact with @Configuration
. You additionally wish to annotate it with @EnableConfigurationProperties
in order that the homes are to be had to the bean.
@Configuration
@EnableConfigurationProperties(MyProperties.elegance)
public elegance ApplicatonConfig {
}
The controller does now not want any additional annotations:
@RestController
public elegance ConfigurationController {
personal ultimate MyProperties myProperties;
@Autowired
public ConfigurationController(MyProperties myProperties) {
this.myProperties = myProperties;
}
...
}
The assessments are similar to the assessments of config1, it will be significant so as to add the @EnableConfigurationProperties
annotation to the @WebMvcTest
assessments.
@ConfigurationProperties + @ConfigurationPropertiesScan
In module config4, you utilize @ConfigurationProperties
to map the homes to elegance MyProperties
. This time, you upload annotation @ConfigurationPropertiesScan
to the category MySpringBootConfigurationPlanetApplication
, the only annotated with @SpringBootApplication
. With the @ConfigurationPropertiesScan
annotation, you’ll be able to additionally specify which applications comprise the configuration categories.
The primary elegance is outlined as follows:
@SpringBootApplication
@ConfigurationPropertiesScan("com.mydeveloperplanet.myspringbootconfigurationplanet.config4.config")
public elegance MySpringBootConfigurationPlanetApplication {
public static void major(String[] args) {
SpringApplication.run(MySpringBootConfigurationPlanetApplication.elegance, args);
}
}
The MyProperties
elegance simplest wishes @ConfigurationProperties
.
@Getter
@Setter
@ConfigurationProperties("my.homes")
public elegance MyProperties {
...
}
The controller does now not want any configuration annotations:
@RestController
public elegance ConfigurationController {
personal ultimate MyProperties myProperties;
@Autowired
public ConfigurationController(MyProperties myProperties) {
this.myProperties = myProperties;
}
...
}
The assessments are once more similar to the assessments of config1.
Constructor Binding
In module config5, you utilize the similar setup as the former config4 module. This time, you’ll use constructor binding within the MyProperties
elegance. The diversities are:
- No wish to specify setters, and the homes can also be made ultimate;
- You wish to have so as to add a constructor to map the configuration;
- Default values wish to be specified by way of the
@DefaultValue
annotation within the constructor argument record; - It’s possible you’ll wish to annotate nested homes with
@DefaultValue
, another way, they’re regarded as to be absent when no assets of the nested assets is assigned a worth.
The MyProperties
elegance is the next:
@Getter
@ConfigurationProperties("my.homes")
public elegance MyProperties {
personal ultimate boolean enabled;
personal ultimate String stringConfig;
personal ultimate Further further;
public MyProperties(boolean enabled, String stringConfig, @DefaultValue Further further) {
this.enabled = enabled;
this.stringConfig = stringConfig;
this.further = further;
}
@Getter
public static elegance Further {
personal ultimate boolean addEnabled;
personal ultimate String addString;
public Further(boolean addEnabled, String addString) {
this.addEnabled = addEnabled;
this.addString = addString;
}
}
}
In the event you omit the @DefaultValue
within the argument record for argument further
and you set assets my.homes.further.add-string
in software.homes
in remark, you’ll realize that the output is:
Worth of enabled = false
Worth of stringConfig = First examine piece
As a substitute of :
Worth of enabled = false
Worth of stringConfig = First examine piece
Worth of extra.addEnabled = false
Worth of extra.addString = null
Whilst you run the WebLayerIT
examine.
The assessments are once more similar to the assessments of config1.
Conclusion
There are a number of choices to be able to configure homes in a Spring Boot software. This publish tries to hide one of the vital choices and explains the variations via instance. The Constructor Binding configuration isn’t the same as the opposite choices as it does now not permit you to adjust the homes all through runtime.
Which one to select? Personally, the @ConfigurationProperties + @ConfigurationPropertiesScan or the Constructor Binding are those to make a choice from, as they require the least annotations. Constructor Binding is much more secure since the homes can’t be changed all through runtime. On the other hand, you must at all times believe the choices in accordance with your use case.
[ad_2]