Spring Boot Configuration Houses Defined

Spring Boot Configuration Houses Defined

[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 furtherconfiguration merchandise consisting of:
    • a boolean addEnabled;
    • a string addString.

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 to WebLayerIT, 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]

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back To Top
0
Would love your thoughts, please comment.x
()
x