Table of Contents
In this tutorial, we are going to see about Spring boot @ConfigurationProperties annotation.
Spring boot @ConfigurationProperties allows you to map properties values with java object easily.
Let’s first see the normal mapping first. Let’s say you have properties file below.
application.properties
1 2 3 4 |
org.blogname=java2blog org.host=hostEasy |
You can access above property file as below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package org.arpit.java2blog; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class BlogDetails { @Value("${org.blogName}") String blogName; @Value("${org.host}") String host; public String getBlogName() { return blogName; } public void setBlogName(String blogName) { this.blogName = blogName; } public String getHost() { return host; } public void setHost(String host) { this.host = host; } } |
So, you can use @Value to get property value from application.properties but it might be tedious to use @Value everywhere,Spring boot provides @ConfigurationProperties to map properties value to java Object.
Let’s understand with the help of example.
Maven dependencies:
Step 2: Change pom.xml as below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.arpit.java2blog</groupId> <artifactId>SpringBootConfigurationPropertiesExample</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>SpringBootConfigurationPropertiesExample</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> |
step 3: Create a package named "org.arpit.java2blog" and class named ServerDetails
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
package org.arpit.java2blog; import java.util.Arrays; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Configuration @ConfigurationProperties(prefix="com.server") public class ServerDetails { String url; String name; int[] port; Application application; public static class Application { String userName; String password; 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 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; } public int[] getPort() { return port; } public void setPort(int[] port) { this.port = port; } public Application getApplication() { return application; } public void setApplication(Application application) { this.application = application; } @Override public String toString() { return "Server Details{" + "name='" + name + '\'' + ", url='" + url + '\'' + ", port='" + Arrays.toString(port) + '\'' + ", username='" + application.getUserName()+ '\'' + ", password='" + application.getPassword()+ '\'' + '}'; } } |
step 4: Make changes to application.properties to add below properties.
1 2 3 4 5 6 7 8 9 10 11 12 |
org.blogName=java2blog org.host=hostEasy com.server.url= dummy.xyz.com com.server.name= amazonEc2 com.server.port[0]=8080 com.server.port[1]=8081 com.server.application.username = admin com.server.application.password = admin123 |
step 5: Create Spring boot main class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package org.arpit.java2blog; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class SpringBootExample { @Autowired ServerDetails serverDetails; public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(SpringBootExample.class, args); } @PostConstruct public void init() { System.out.println(serverDetails.toString()); } } |
As you can see, we have used @Autowired to inject ServerDetails to SpringBootExample.
Step 6: Run the application.
When you run above example, you will get below output.
. ____ _ __ _ _
/\\ / ___’_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | ‘_ | ‘_| | ‘_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
‘ |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.3.RELEASE)
2018-07-14 23:53:47.766 INFO 67832 — [ main] org.arpit.java2blog.SpringBootExample : Starting SpringBootExample on apples-MacBook-Air.local with PID 67832 (/Users/apple/Downloads/SpringBootConfigurationPropertiesExample/target/classes started by apple in /Users/apple/Downloads/SpringBootConfigurationPropertiesExample)
2018-07-14 23:53:47.774 INFO 67832 — [ main] org.arpit.java2blog.SpringBootExample : No active profile set, falling back to default profiles: default
2018-07-14 23:53:47.901 INFO 67832 — [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@429bd883: startup date [Sat Jul 14 23:53:47 IST 2018]; root of context hierarchy
Server Details{name=’amazonEc2′, url=’dummy.xyz.com’, port='[8080, 8081]’, username=’admin’, password=’admin123′}
2018-07-14 23:53:49.000 INFO 67832 — [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-07-14 23:53:49.024 INFO 67832 — [ main] org.arpit.java2blog.SpringBootExample : Started SpringBootExample in 2.252 seconds (JVM running for 3.406)
2018-07-14 23:53:49.028 INFO 67832 — [ Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@429bd883: startup date [Sat Jul 14 23:53:47 IST 2018]; root of context hierarchy
2018-07-14 23:53:49.030 INFO 67832 — [ Thread-2] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
Here is the picture which will help you understand @ConfigurationProperties better.
Relaxed binding
One of the interesting feature of Spring boot is relaxed binding.
for com.server.application.username, below are valid spring boot bindings.
- com.server.application.user_name(with _)
- com.server.application.user-name(with -)
- com.server.application.USER_NAME(with uppercase)
Custom property file
You can use custom property as well instead of application.property using @PropertySource annotation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package org.arpit.java2blog; import java.util.Arrays; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Configuration @PropertySource("classpath:custom.properties") @ConfigurationProperties(prefix="com.server") public class ServerDetails { .. } |
Validation
We can use JSR-303 Validation API to validate properties.You need to add below dependency.
1 2 3 4 5 6 7 8 |
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.10.Final</version> <relativePath/> </dependency> |
For example:
Let’s say you want to restrict username from 5 to 8 characters, you can use @Length annotaton as below.
1 2 3 4 |
@Length(max = 8, min = 5) String userName; |
If you change userName to adam
1 2 3 |
com.server.application.username = adam |
You will get below validation error.
Value: adam
Reason: length must be between 5 and 8
That’s all about Spring boot @ConfigurationProperties.