ivanursul

How to map Spring Boot properties to Java class

Have you ever had a need to use some values from application.properties or **application.yml? How did you take them out?

Personally, I always used @Value annotation:

    @Value("${graphite.host}")
    private String graphiteHost;

It wasn’t the best way to work with my properties. However, I didn’t know a better approach.

Then, I found @ConfigurationProperties - annotation from Boot package, which has everything you need to map your properties.

Given

Let’s say, your application.yml looks like following:

graphite:
  enabled: true
  host: localhost
  port: 2003
  amountOfTimeBetweenPolls: 20000

When

You need to create a bunch of classes, which you will be autowiring in all parts of your code.

I’m using Project Lombok for skipping java formalities, if you are not, then create getters and setters for your classes.

package org.rngr.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import javax.validation.constraints.NotNull;

@ConfigurationProperties(ignoreUnknownFields = true)
@Data
public class ApplicationProperties {

    @NotNull
    private GraphiteProperties graphite;

}

Pay attention to @ConfigurationProperties annotation, it’s playing a key role here.

Don’t forget about subclass:

package org.rngr.properties;

import lombok.Data;

@Data
public class GraphiteProperties {

    private boolean enabled;
    private String host;
    private int port;
    private int amountOfTimeBetweenPolls;

}

In the end, you need to enable configuration properties:

package org.rngr;

import lombok.extern.slf4j.Slf4j;
import org.rngr.config.*;
import org.rngr.properties.ApplicationProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@Import({
		MonitoringConfiguration.class
})
@Configuration
@EnableConfigurationProperties(ApplicationProperties.class)
public class WebappApplication {

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

Then

Then, you are free to Autowire ApplicationProperties instance wherever you want:

    ...
    @Autowired
    private ApplicationProperties properties;
    ...

Conclusions

I guess, this approach was borrowed from Dropwizard framework. One good thing about introducing configuration properties class is that you will get power to validate them.

I remember a few years ago there was a broad discussion about pros and cons of switching to Java configuration. For me, Configuration properties and their transformation to ConfigurationProperties class is something similar.