Configuration properties - type-safe Configuration Management

While the ;@Value annotation provides dynamic configuration, it also has several drawbacks:

  • If we want to use three property values in a service, we would need to autowire ;them using @Value three times.
  • The @Value annotations and the keys of the messages would be spread across the application. If we want to find the list of the configurable values in an application, we have to search through the application for @Value annotations.

Spring Boot provides a better approach to application configuration through the strongly typed ConfigurationProperties feature. This allows us to do the following:

  • Have all the properties in a predefined bean structure
  • This bean would act as the centralized store for all application properties
  • The configuration bean can be autowired wherever application configuration is needed

An example configuration bean is shown as follows:

    @Component
@ConfigurationProperties("application")
public class ApplicationConfiguration {
private boolean enableSwitchForService1;
private String service1Url;
private int service1Timeout;
public boolean isEnableSwitchForService1() {
return enableSwitchForService1;
}
public void setEnableSwitchForService1
(boolean enableSwitchForService1) {
this.enableSwitchForService1 = enableSwitchForService1;
}
public String getService1Url() {
return service1Url;
}
public void setService1Url(String service1Url) {
this.service1Url = service1Url;
}
public int getService1Timeout() {
return service1Timeout;
}
public void setService1Timeout(int service1Timeout) {
this.service1Timeout = service1Timeout;
}
}

A couple of important things to note are as follows:

  • @ConfigurationProperties("application") is the annotation for an externalized configuration. We can add this annotation to any class to bind to external properties. The value in the double quotes--application--is used as a prefix while binding external configuration to this bean.
  • We are defining multiple configurable values in the bean.
  • Getters and setters are needed since binding happens through Java beans property descriptors.

The following snippet shows how the values for these properties can be defined in application.properties:

    application.enableSwitchForService1=true
application.service1Url=http://abc-dev.service.com/somethingelse
application.service1Timeout=250

A couple of important things to note are as follows:

  • application: The prefix is defined as part of @ConfigurationProperties("application") while defining the configuration bean
  • Values are defined by appending the prefix to the name of the property

We can use configuration properties in other beans by autowiring ApplicationConfiguration into the bean:

    @Component
public class SomeOtherDataService {
@Autowired
private ApplicationConfiguration configuration;
public String retrieveSomeData() {
// Logic using the url and getting the data
System.out.println(configuration.getService1Timeout());
System.out.println(configuration.getService1Url());
System.out.println(configuration.isEnableSwitchForService1());
return "data from service";
}
}

A couple of important things to note are as follows:

  • @Autowired private ApplicationConfiguration configuration: ApplicationConfiguration is autowired into SomeOtherDataService
  • configuration.getService1Timeout(), configuration.getService1Url(), configuration.isEnableSwitchForService1(): Values can be accessed in bean methods using the getter methods on the configuration bean

By default, any failure in binding externally configured values to configuration properties bean would result in the failure of the server start up. This prevents problems that arise because of misconfigured applications running in production.

Let's use the misconfigure service timeout to see what happens:

    application.service1Timeout=SOME_MISCONFIGURATION

The application will fail to start up with an error.

 ***************************
APPLICATION FAILED TO START
***************************
Description:
Binding to target com.mastering.spring.springboot.configuration.ApplicationConfiguration@79d3473e failed:

Property: application.service1Timeout
Value: SOME_MISCONFIGURATION
Reason: Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'service1Timeout'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [int]

Action:
Update your application's configuration
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset