Binding External Configuration properties in spring boot application

23 / Jul / 2015 by Ashu Kohli 0 comments

Hi,

In this blog we’ll learn how we can inject configuration properties in a springBoot application and what are the benefits of spring boot over spring while injecting configuration properties.

There are two ways to inject our configuration properties:-

1. By Using @Value annotation (Spring 3.0+ And Grails 3.0)
2. Typesafe Configuration Properties (Sring-Boot)

Lets suppoese we have a yaml(application.yml) as configuration file, i.e., the following YAML document:

es:
  hosts: ['5.9.154.115']
  port: 10600
  cluster : 'elasticsearch'

We can also use the properties file(application.properties) for external configuration, the properties file version for the above yml file would be:-

es.hosts[0]='5.9.154.115'
es.port=10600
es.cluster='elasticsearch'

1. Using @Value annotation we can inject the configuration properties into our application. Syntax would be @Value(#{property_name}).

For example, the following class represent binding the external configuration in a class using the @value annotation :-

@Configuration
public class SpringConfig {
    static Client esClient

    @Value("#{es.hosts}")
    List hosts

    @Value("#{es.port}")
    int port

    @Value("#{es.cluster}")
    String cluster

    @Bean
    Client getClient() {
        if (!esClient) {
            Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name", cluster).build();
            TransportClient transportClient = new TransportClient(settings);
            for (String esHostName : hosts) {
                transportClient = transportClient.addTransportAddress(new InetSocketTransportAddress(esHostName, port));
            }
            esClient = transportClient

        }

        return esClient
    }
}

The ‘springConfig’ class properties i.e. hosts , port and cluster will automatically bind with their corresponding match with external configuration file, hosts will bind to es.hosts, port bind to es.port and so on.

We can also define the default value in @Value annotation using Elvis operator(?:). Syntax for the same is: #{expression?:default value}.

For Example :
@Value("#{es.port?:9200}")

Note: Using the @Value(“#{property_name}”) annotation to inject configuration properties can sometimes be confusing, especially if we are working with multiple properties.

2. Typesafe Configuration Properties:- Spring Boot provides an alternative method of working with configuration properties that allows strongly typed beans to inject and validate the configuration properties of our application.

For example, the following class represent binding the external configuration in a class using @ConfigurationProperties annotation :-

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "es")
class SpringConfig {
    static Client esClient

    List hosts
    int port
    String cluster

    @Bean
    Client getClient() {
        if (!esClient) {
            Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name", cluster).build();
            TransportClient transportClient = new  TransportClient(settings);
            for (String esHostName : hosts) {
                transportClient = transportClient.addTransportAddress(new InetSocketTransportAddress(esHostName, port));
            }
            esClient = transportClient

        }

        return esClient
    }
}

In @ConfigurationProperties annotation we can define property’s prefix. In our case any property defined with the ‘es’ prefix will be mapped onto that ‘SpringConfig’ bean, hosts will bind to es.hosts, port bind to es.port and so on.

To validate the external configuaration we can use JSR-303(javax.validate) constraints annotations to our @ConfiqurationPropertis class

For Example:-

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "es")
class SpringConfig {
    static Client esClient

    @NotNull
    List hosts

    @NotNull
    int port

    @NotNull
    String cluster

    @Bean
    Client getClient() {
        if (!esClient) {
            Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name", cluster).build();
            TransportClient transportClient = new  TransportClient(settings);
            for (String esHostName : hosts) {
                transportClient = transportClient.addTransportAddress(new InetSocketTransportAddress(esHostName, port));
            }
            esClient = transportClient

        }

        return esClient
    }
}

The above @ConfiqurationProperties class will validate against null values. And we can also add a custom Spring Validator by creating a bean definition called ConfigurationPropertiesValidator.

Hope this helps you :)

Get in touch with our team to discuss your project on Spring.

FOUND THIS USEFUL? SHARE IT

Leave a comment -