Inject Properties from Properties File using @ConfigurationProperties Annotation

This tutorial will show you the better way to handle properties using @ConfigurationProperties Annotation.

In previous article, we have learned about using @Value annotation to inject properties from properties file. This approach has disadvantage that if we wanna change any property, we have to update all files which referenced it.

I. Technology

– Java 1.8
– Maven 3.3.9
– Spring Tool Suite – Version 3.8.1.RELEASE (It’s OK if you use Eclipse)

II. Overview

1. Project Structure

configproperties-structure1

– In the project, we use a separate configuration properties classes annotated with @ConfigurationProperties, so property values can be bound to structured objects conveniently.
With this approach, when we wanna find or change the handling properties object, we just notice a separate component class. In this example, it is class AppicationProperties.

– For configuration class of the whole application (AppConfig.java), we should enable class above by using @EnableConfigurationProperties annotation.

– To get environment properties value, we create a Service and inject AppicationProperties object and use getter methods easily.

2. Step to do

– Create Maven project
– Add Dependencies & Plugins
– Add Properties File
– Create Properties Class
– Create Configuration Class
– Create a Service
– Create MainApplication Class
– Run Application & Enjoy Result

III. Practice

1. Create Maven project

– Open Spring Tool Suite, on Menu, choose File -> New -> Maven Project.
– Check Create a simple project, choose Workspace Location and click Next.
– Fill all fields in Artifact group box, then click Finish.

2. Add Dependencies & Plugins

Open pom.xml, add:

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.4.0.RELEASE</version>
	<relativePath />
</parent>

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot</artifactId>
	</dependency>

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-configuration-processor</artifactId>
		<optional>true</optional>
	</dependency>

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-validation</artifactId>
	</dependency>
</dependencies>

<build>
	<pluginManagement>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.3</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</pluginManagement>
</build>

3. Add Properties File

Under src/main/resources, add properties file:

myapp.properties


app.connection.url=https://ozenero.com
app.connection.name=Java Sample Approach
app.host=localhost
app.port=123
app.username=admin
app.password=

4. Create Properties Class

Under package config/properties, create ApplicationProperties.java:


package com.javasampleapproach.configproperties.config.properties;

import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.NotBlank;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(ignoreUnknownFields = false, prefix = "app")
public class ApplicationProperties {
	@NotNull
	private Connection connection;
	@NotBlank
	private String host;
	@Max(value = 65535)
	private int port;
	@NotBlank
	private String username;
	// @NotBlank
	private String password;

	public Connection getConnection() {
		return connection;
	}

	public void setConnection(Connection connection) {
		this.connection = connection;
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public static class Connection {
		private String url;
		private String name;

		public String getUrl() {
			return url;
		}

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

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}
	}
}

prefix = “app” indicates that any property defined with the app prefix will be mapped onto ApplicationProperties bean.

ignoreUnknownFields = false helps to throw an exception when there is any property which doesn’t match any declared field in the configuration properties class.

– to make sure that our application fails fast at the beginning instead of misbehaving, we add Validation Annotation @NotNull, @NotBlank, @Max… before fields of class.

– in case of nested key-values, we can use a custom structure comfortably, just create an inner class with appropriate properties and getters/setters. In this example, to match with connection[url,name], we have Connection class with 2 members: url and name.

5. Create Configuration Class

Under package config, create AppConfig.java:


package com.javasampleapproach.configproperties.config;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import com.javasampleapproach.configproperties.config.properties.ApplicationProperties;

@Configuration
@EnableConfigurationProperties(ApplicationProperties.class)
@PropertySource("myapp.properties")
@ComponentScan(basePackages = "com.javasampleapproach.configproperties")
public class AppConfig {
}

6. Create a Service

Under package service, create interface for Service and implementation of that interface.

MyService.java


package com.javasampleapproach.configproperties.service;

public interface MyService {
	public String getValue();
}

MyServiceImp.java


package com.javasampleapproach.configproperties.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.javasampleapproach.configproperties.config.properties.ApplicationProperties;

@Service("service")
public class MyServiceImp implements MyService {

	private ApplicationProperties applicationProperties;

	@Autowired
	public MyServiceImp(ApplicationProperties applicationProperties) {
		this.applicationProperties = applicationProperties;
	}

	@Override
	public String getValue() {
		String result = "Properties Values from Properties File:\n";

		result += "- getConnection().getName(): " + applicationProperties.getConnection().getName() + "\n";
		result += "- getConnection().getUrl(): " + applicationProperties.getConnection().getUrl() + "\n";
		result += "- getHost(): " + applicationProperties.getHost() + "\n";
		result += "- getPort(): " + applicationProperties.getPort() + "\n";
		result += "- getUsername(): " + applicationProperties.getUsername() + "\n";
		result += "- getPassword(): " + applicationProperties.getPassword() + "\n";

		return result;
	}
}

7. Create MainApplication Class

MainApp.java


package com.javasampleapproach.configproperties;

import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.AbstractApplicationContext;

import com.javasampleapproach.configproperties.config.AppConfig;
import com.javasampleapproach.configproperties.service.MyService;

@SpringBootConfiguration
public class MainApp {

	public static void main(String[] args) {
		AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		
		MyService myService = (MyService) context.getBean("service");
		System.out.println(myService.getValue());
		
		context.close();
	}
}

8. Run Application & Enjoy Result

– Config maven build:
clean install
– Run project with mode Spring Boot App
– Check results in Console Screen:


Properties Values from Properties File:
- getConnection().getName(): Java Sample Approach
- getConnection().getUrl(): https://ozenero.com
- getHost(): localhost
- getPort(): 123
- getUsername(): admin
- getPassword(): 

IV. Source Code

spring-config-properties

One thought on “Inject Properties from Properties File using @ConfigurationProperties Annotation”

Leave a Reply

Your email address will not be published. Required fields are marked *