Open In App

Spring Boot – @ConfigurationProperties

In Spring Boot, @ConfigurationProperties Annotation allows the developer to map the entire content of the properties file to a POJO (Plain Old Java Object). A property file can be either application.properties or application.yml. This annotation is useful when we have a large set of explicit configurations defined in the properties file. It provides an organized and Java-specific approach to defining the properties. We can cluster similar sets or properties to multiple POJOs.

In this article, we’ll discuss the @ConfigurationProperties Annotation of Spring Boot Framework for that supports binding an external property file to a Java Object.



@ConfigurationProperties in Spring Boot

A real-world example to better understand the isolation of a properties file in a separate POJO would be:

You can organize all your books on your table depending on their genres but the problem with this approach is that you’ll have to go through the covers of one or more books to identify which genre this particular stack belongs to. Now, imagine putting them on a shelf, and labeling the partitions of the shelf with books of each type wouldn’t that be easy? Isolating property files in separate POJOs allows you to achieve similar functionality.



It is also recommended by Spring Framework’s official document to isolate property files in separate POJOs.

Step-By-Step Implementation

Step 1: Go to Spring Initalizr and download and extract a starter file.

We need following set of things:

pom.xml File:




<?xml version="1.0" encoding="UTF-8"?>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.GeeksForGeeks</groupId>
    <artifactId>ConfigurationProperties</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ConfigurationProperties</name>
    <description>Demo project for @ConfigurationProperties</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
  
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
  
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </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>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
  
</project>

Step 2: Organize directory structure

Final directory structure should look like this:

Step 3: Create a properties file

Store the following properties under – “src/main/resources/application.properties”

#1 Server Configuration Properties
server.port=8080
server.contextPath=/myPropertiesApp
server.connectionTimeout=5000

#2 Database Configuration Properties
spring.datasource.url=jdbc:mysql://localhost:3306/geeksforgeeks
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root


Step 4: Define Configuration Properties classes.

1. Server Properties Class

It is a simple plain old Java object defined for storing server type properties. Annotations used here have a significant impact on our Java Object’s working:




import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.springframework.validation.annotation.Validated;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
  
// POJO for Server Property type
@Component
@Data
@Validated
@ConfigurationProperties(prefix = "server")
public class ServerProperties {
      
      // Range of port numbers
      @Min(1025)
    @Max(65535)
    private int port;
  
      // NotBlank indicates this property cannot be left blank
    @NotBlank(message = "Context path cannot be blank!")
    private String contextPath;
      
      // Specifying the default value if none is given inside properties file
    @Value("${server.connectionTimeout:5000}")
    private int connectionTimeout;
  
}

2. Database Configuration Properties Class

It is also a Plain Old Java Object defined for mapping database configuration properties, and we’ve also provided a prefix spring.datasource indicating all the properties starting with this will be mapped to this POJO.




import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
  
// POJO for Database Configuration Property type
@Component
@Data
@Validated
@ConfigurationProperties(prefix = "spring.datasource")
public class DatabaseConfigProperties {
    @NotBlank(message = "URL field cannot be Blank!")
    private String url;
  
    @NotBlank(message = "You should specify the appropriate driver class!")
    private String driverClassName;
  
    @NotBlank(message = "Username field cannot be Blank!")
    private String username;
  
    @NotBlank(message = "Password field can not be Blank!")
    private String password;
}

Step 5: Create REST Controller to fetch & verify the mapping of properties from property file to POJOs

REST Controller:




import com.GeeksForGeeks.ConfigurationProperties.ConfigProperties.DatabaseConfigProperties;
import com.GeeksForGeeks.ConfigurationProperties.ConfigProperties.ServerProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
  
// Controller to test Properties POJOs
@RestController
@RequestMapping("/properties")
public class TestController {
  
    // Field Injection
    @Autowired
    ServerProperties serverProperties;
  
    // Field Injection
    @Autowired
    DatabaseConfigProperties databaseConfigProperties;
  
    // Get Server Properties
    @GetMapping("/server")
    public ServerProperties getServerProperties() {
        return serverProperties;
    }
  
    // Get Database Properties
    @GetMapping("/database")
    public DatabaseConfigProperties getDatabaseProperties() {
        return databaseConfigProperties;
    }
}

Explanation of the above Program:

The above REST Controller defined, allows us to verify if the properties defined inside application.properties are mapped and stored properly in a POJO. We have defined following REST Endpoints:

We can define more properties and map them similarly by creating a separate POJO for each type. This approach promotes separation of concern and easily verify the mappings.

Output on PostMan:

1. http://localhost:8080/properties/server

2. http://localhost:8080/properties/database

Advantages

Disadvantages

Conclusion

In conclusion, the @ConfigurationProperties is a way to map properties defined inside an application.properties file to a Java Object. This approach provides ease of access, validation, management, organization and improve the code readability of our application. Following are major key takeaways:


Article Tags :