Spring-Boot Configuration Properties

I wanted to switch in my spring-boot microservices project from hard coded values to configurable ones:

// ...
JsonNode json = restTemplate.postForObject("http://localhost:8081/login",
  payload, ObjectNode.class);
// ...

The easiest way to configure anything in spring-boot is through application.properties. By default, spring-boot looks for the application.properties in the /config folder first, so I placed one there with the desired value in it:

~/microservices/webservice % cat src/main/resources/config/application.properties 


~/microservices/webservice %

There are two ways to access configuration values in spring-boot: using the @Value annontation or with structured objects. I’m going to use the structured objects, because the @Value annotation can be cubersome to use when it comes to types (and it is also a bit hard to mock it in testing):

package com.zsoltfabok.webservice.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

public class ServicesProperties {

    private Authservice authservice = new Authservice();

    public static class Authservice {
        private String url;

        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }

    public Authservice getAuthservice() { return authservice; }
    public void setAuthservice(Authservice authservice)
      { this.authservice = authservice; }

The ServiceProperties is bounded to all the variables that start with the word services. The authservice is a sub level property and as such spring-boot reaches it with a static sub class. Mind that the getters and setters must much the configuration name. For example, in my case the getAuthService() and setAuthService() methods did nothing, and when I asked for the value, the system returned null.

In order to use the class above I had to do two things. First, tell spring-boot to load it with the @EnableConfigurationProperties annotation:

public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);

Second, inject it into my contoller (that’s why the properties file is annotated with @Component):

public class LoginController {

    private ServicesProperties servicesProperties;

    // ...

Using the property:

// ...
String authserviceUrl = servicesProperties.getAuthservice().getUrl();
JsonNode json = restTemplate.postForObject(authserviceUrl,
  payload, ObjectNode.class);
// ...

Since it is autowired, mocking it in testing is also easy:

public class LoginControllerTest {
	// ...

    private ServicesProperties servicesProperties;

    public void setup() {
        authserviceUrl = "url";

    // ...

The answer=Answers.RETURNS_DEEP_STUBS tells mockito to allow to mock chain of methods. Otherwise, I had to create a mock for ServicesProperties and another one for the ServicesProperties.Authservice.

comments powered by Disqus