Open In App

Changing Spring Boot Properties at Runtime

Last Updated : 17 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Spring Boot provides a flexible way to configure application properties, typically defined statically in the application.properties or application.yml files. However, there are scenarios where properties need to be changed dynamically at runtime without restarting the application. In this article, we will explore how to change Spring Boot properties at runtime and the different methods to achieve this.

Changing Properties in Spring Boot at Runtime

Changing properties at runtime involves updating the application's configuration without requiring a restart. This can be particularly useful for adjusting settings dynamically based on user input, environmental changes, or operational requirements.

Spring Boot applications are typically configured using properties files (application.properties or application.yml). These files are read at startup, and changes generally require a restart to take effect. However, it is sometimes necessary to update configuration settings while the application is running.

Key Components

  • Environment Abstraction: Provides access to the application's configuration properties and allows for programmatic access and manipulation of the properties.
  • PropertySources: Mechanism for adding, removing, or modifying property sources dynamically. This includes PropertiesPropertySource, which is a common way to create new property sources from Properties objects.
  • Spring Cloud Config: For more complex scenarios involving multiple services or dynamic configuration across distributed systems, Spring Cloud Config provides a centralized configuration server.

Project Implementation to Change Properties at Runtime in Spring Boot

This example demonstrates how to change Spring Boot properties at runtime. We will create a simple Spring Boot application with a REST API that allows updating and retrieving properties dynamically.

Step 1: Create the New Spring Boot Project

Create a new Spring Boot project using IntelliJ IDEA with the following options:

  • Name: dynamic-property-management
  • Language: Java
  • Type: Maven
  • Packaging: Jar

Click Next and proceed with the default settings.

Project Metadata

Step 2: Add Dependencies

Add the following dependencies into the Spring Boot project.

  • Spring Web
  • Lombok
  • Spring DevTools
  • Spring Boot Actuator

Click on the Create button.

Add Dependencies

Project Structure

After creation, the project structure should look like this:

Project Folder Structure

Step 3: Configure Application Properties

Open the application.properties file and add the following configuration:

spring.application.name=dynamic-property-management
app.mode=production

Step 4: Create the PropertyService Class

Create the PropertyService class to handle property operations.

PropertyService.java:

Java
package com.gfg.dynamicpropertymanagement;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.stereotype.Service;

import java.util.Properties;

@Service
public class PropertyService {

    @Autowired
    private ConfigurableEnvironment environment;

    /**
     * Updates a property in the environment.
     * 
     * @param key The property key to update.
     * @param value The new value for the property.
     */
    public void updateProperty(String key, String value) {
        MutablePropertySources propertySources = environment.getPropertySources();
        Properties props = new Properties();
        props.put(key, value);
        PropertiesPropertySource propertySource = new PropertiesPropertySource("dynamicProps", props);
        propertySources.addFirst(propertySource);
    }

    /**
     * Retrieves a property value from the environment.
     * 
     * @param key The property key to retrieve.
     * @return The current value of the property.
     */
    public String getProperty(String key) {
        return environment.getProperty(key);
    }
}
  • updateProperty(): Adds or updates a property at runtime by creating a new PropertiesPropertySource and adding it to the environment's property sources.
  • getProperty(): Retrieves the current value of a property from the environment.

Step 5: Create the ConfigController Class

Create the ConfigController class to provide REST endpoints for updating and retrieving properties.

ConfigController.java:

Java
package com.gfg.dynamicpropertymanagement;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.web.bind.annotation.*;

import java.util.Properties;

@RestController
@RequestMapping("/api/config")
public class ConfigController {

    @Autowired
    private ConfigurableEnvironment environment;

    /**
     * Endpoint to update a property at runtime.
     * 
     * @param key The property key to update.
     * @param value The new value for the property.
     * @return Confirmation message.
     */
    @PostMapping("/update")
    public String updateProperty(@RequestParam String key, @RequestParam String value) {
        MutablePropertySources propertySources = environment.getPropertySources();
        Properties props = new Properties();
        props.put(key, value);
        PropertiesPropertySource propertySource = new PropertiesPropertySource("dynamicProps", props);
        propertySources.addFirst(propertySource);
        return "Property updated: " + key + " = " + value;
    }

    /**
     * Endpoint to retrieve the current value of a property.
     * 
     * @param key The property key to retrieve.
     * @return The current value of the property.
     */
    @GetMapping("/get")
    public String getProperty(@RequestParam String key) {
        return key + " = " + environment.getProperty(key);
    }
}

Explanation:

  • updateProperty(): Handles POST requests to update a property dynamically.
  • getProperty(): Handles GET requests to retrieve the current value of a property.

Step 6: Main class

No changes are required in the main class.

Java
package com.gfg.dynamicpropertymanagement;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DynamicPropertyManagementApplication {

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

}

pom.xml File:

XML
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gfg</groupId>
    <artifactId>dynamic-property-management</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>dynamic-property-management</name>
    <description>dynamic-property-management</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </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 7: Run the Application

Now, start the application. It will run on port 8080.

Application Started

Step 8: Testing the Application

Open the postman tool to send the below request to update property at the runtime.

Update Property:

POST http://localhost:8080/api/config/update?key=app.mode&value=development

Response:

Update Property


Retrieve Property:

GET http://localhost:8080/api/config/get?key=app.mode

Response:

Retrieve Property

This example demonstrates how to dynamically update and retrieve the properties in the Spring Boot application using the Environment abstraction.


Next Article

Similar Reads