Popular Searches
Popular Course Categories
Popular Courses

Managing Configuration Using Externalized Properties

Managing Configuration Using Externalized Properties

Spring Boot Application Development

Managing Configuration Using Externalized Properties

Course: Advanced Java Training

Topic: Managing Configuration Using Externalized Properties in Spring Boot

Course Link: Advanced Java Training Course

Demo Link: Register for a Course Demo

JustAcademy Website: Visit JustAcademy


1. Introduction to Externalized Configuration

Externalized configuration is a software development practice in which application settings are maintained separately from the application's Java source code. In Spring Boot, externalized properties allow developers to configure application behavior without changing or recompiling business logic every time a setting changes.

Applications commonly require configuration values such as server ports, database URLs, logging levels, API endpoints, file paths, feature flags, and integration settings. Hardcoding these values in Java classes makes applications more difficult to maintain and deploy across different environments.

Spring Boot supports external configuration through properties files, YAML files, environment variables, Java system properties, command-line arguments, and other supported property sources.

Why Is Externalized Configuration Important?

  • Environment flexibility: The same application artifact can run with different development, testing, and production settings.
  • Maintainability: Configuration can be updated without modifying business logic.
  • Deployment flexibility: Deployment tools can supply settings through environment variables or command-line arguments.
  • Security: Sensitive values can be supplied through protected environment settings or secret-management systems rather than committed to source code.
  • Consistency: Teams can establish standardized configuration conventions.
  • Testing: Tests can use dedicated settings without changing production configuration.

2. Understanding Property Sources in Spring Boot

A property source is a location or mechanism from which Spring Boot obtains configuration values. When the application requests a property, Spring resolves it from the available configuration sources according to the framework's property-resolution rules and precedence.

Common Property Sources

Property Source Description Example
application.properties Stores configuration as key-value pairs. server.port=8081
application.yml Stores configuration in a hierarchical YAML structure. server: followed by an indented port value.
Environment variables Supplies values from the operating system or deployment environment. SERVER_PORT=9090
Java system properties Supplies properties through JVM startup options. -Dserver.port=9090
Command-line arguments Supplies configuration when launching the application. --server.port=9090
External configuration files Stores settings outside the packaged application. An external application.properties file.
Profile-specific files Provides settings for a particular environment or profile. application-prod.properties
Custom property sources Allows applications to add supported configuration sources programmatically. A custom property source registered with Spring.

The exact precedence depends on the property source and how the application is launched. For common Spring Boot configuration, command-line arguments generally override Java system properties, environment variables, and packaged configuration files.

3. Using application.properties

The application.properties file is a standard location for Spring Boot settings. It is commonly stored in src/main/resources.

Example Configuration

spring.application.name=employee-management
server.port=8081

app.company.name=ABC Technologies
app.company.location=Mumbai

logging.level.root=INFO
logging.level.com.example.employee=DEBUG

Explanation

  • spring.application.name defines the application name.
  • server.port configures the embedded web server's listening port.
  • app.company.name and app.company.location are custom application properties.
  • logging.level.root configures the root logging level.
  • logging.level.com.example.employee sets the logging level for the specified package.

Spring Boot recognizes its documented properties automatically. Custom properties must be read by the application, for example through @Value or @ConfigurationProperties.

4. Using application.yml

YAML provides a structured alternative to properties files. It represents related configuration values using nested keys and indentation.

Example Configuration

spring:
  application:
    name: employee-management

server:
  port: 8081

app:
  company:
    name: ABC Technologies
    location: Mumbai

logging:
  level:
    root: INFO
    com.example.employee: DEBUG

In this example, the YAML keys represent the same configuration structure that can be expressed through dotted properties keys. Use consistent indentation with spaces and avoid duplicate keys at the same level.

Properties vs. YAML

Feature Properties YAML
File extension .properties .yml or .yaml
Format Key-value pairs Hierarchical mappings and lists
Nested configuration Usually uses dotted names Uses indentation
Comments Use # Use #
Common issue Incorrect property names or values Incorrect indentation or invalid YAML syntax

Both formats are supported by Spring Boot. Choose the format that best matches the team's conventions and the complexity of the configuration.

5. Accessing Externalized Properties in Java

Spring Boot provides several ways to access configuration values inside Java classes. The most commonly used approaches are @Value, Environment, and @ConfigurationProperties.

5.1 Using @Value

The @Value annotation injects an individual property into a Spring-managed component. It is suitable for small numbers of configuration values.

application.properties

app.company.name=ABC Technologies
app.company.location=Mumbai

CompanyInformation.java

package com.example.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class CompanyInformation {

    @Value("${app.company.name}")
    private String companyName;

    @Value("${app.company.location}")
    private String location;

    public void displayInformation() {
        System.out.println("Company: " + companyName);
        System.out.println("Location: " + location);
    }
}

Explanation:

  • @Component registers the class as a Spring-managed bean.
  • @Value("${app.company.name}") retrieves the company name from the available property sources.
  • @Value("${app.company.location}") retrieves the location.
  • Spring injects the resolved values when creating the bean.

You can provide a default value if a property is not defined:

@Value("${app.company.name:Default Company}")
private String companyName;

5.2 Using the Environment Interface

Spring's Environment abstraction allows a component to retrieve configuration values dynamically by property name. It is useful when a class needs to inspect multiple properties or query the active environment.

package com.example.demo;

import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

@Component
public class ApplicationSettings {

    private final Environment environment;

    public ApplicationSettings(Environment environment) {
        this.environment = environment;
    }

    public void printSettings() {
        String appName = environment.getProperty(
            "spring.application.name", "demo-application"
        );

        String port = environment.getProperty(
            "server.port", "8080"
        );

        System.out.println("Application: " + appName);
        System.out.println("Configured port: " + port);
    }
}

The getProperty() method can return a default value when the requested property is unavailable. Use this approach when direct access to the environment is useful, rather than as a replacement for structured configuration in every class.

5.3 Using @ConfigurationProperties

For multiple related settings, @ConfigurationProperties is generally preferable because it groups configuration into a structured Java object and supports type conversion and validation.

application.properties

app.company.name=ABC Technologies
app.company.location=Mumbai
app.company.employee-count=150

CompanyProperties.java

package com.example.demo.config;

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

@ConfigurationProperties(prefix = "app.company")
public class CompanyProperties {

    private String name;
    private String location;
    private int employeeCount;

    public String getName() {
        return name;
    }

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

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public int getEmployeeCount() {
        return employeeCount;
    }

    public void setEmployeeCount(int employeeCount) {
        this.employeeCount = employeeCount;
    }
}

Register the properties class by adding @ConfigurationPropertiesScan to the main application class, or by using @EnableConfigurationProperties(CompanyProperties.class) in a configuration class.

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;

@SpringBootApplication
@ConfigurationPropertiesScan
public class DemoApplication {

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

Inject the configuration object into a service or controller using constructor injection. The properties class can then be used wherever those settings are needed.

Comparison of Configuration Access Methods

Method Best Use Case Main Advantage
@Value A small number of individual settings. Simple property injection.
Environment Programmatic property lookup. Can query property values by name.
@ConfigurationProperties Groups of related settings. Structured, type-safe configuration binding and support for validation.

6. Understanding Configuration Precedence

Spring Boot can read a property from several sources. If the same property is defined in multiple places, Spring Boot resolves it according to the precedence rules of those sources.

For example, suppose the packaged configuration contains:

server.port=8080

You can override that value when starting the application:

java -jar target/demo.jar --server.port=9090

The command-line argument normally takes precedence over the packaged file, so the application attempts to use port 9090.

Common Configuration Sources

  • Configuration files packaged inside the application.
  • Profile-specific configuration files.
  • External configuration files.
  • Operating-system environment variables.
  • Java system properties.
  • Command-line arguments.
  • Test-specific property sources when running tests.

The complete precedence order is more detailed than this list and includes additional sources. When diagnosing a value that does not match the file, consult the official Spring Boot Externalized Configuration documentation.

7. Managing External Configuration Files

By default, Spring Boot searches for application configuration in recognized classpath and filesystem locations. Keeping configuration outside the packaged JAR can allow deployment settings to change without rebuilding the application.

Example Project Structure

employee-management/
├── src/
│   └── main/
│       ├── java/
│       └── resources/
│           └── application.properties
├── config/
│   └── application.properties
├── pom.xml
└── target/
    └── employee-management.jar

For a deployed application, the external config/application.properties file may override corresponding values from the packaged configuration when it is found in a recognized location.

Using an Additional Configuration Location

The spring.config.additional-location setting adds configuration locations while retaining the default search locations.

java -jar employee-management.jar \
  --spring.config.additional-location=optional:file:./config/

The example uses a Unix-style line continuation. On Windows Command Prompt, enter the command on one line or use the appropriate continuation syntax for the shell.

The optional: prefix allows startup to continue if the specified location does not exist. Without it, a missing required configuration location can prevent startup.

Difference Between Location and Additional Location

Property Purpose
spring.config.location Specifies configuration locations and replaces the default search locations.
spring.config.additional-location Adds configuration locations to the default search locations.
spring.config.name Changes the basename Spring Boot uses when searching for configuration files.
spring.config.import Imports additional configuration data from supported locations.

These settings are processed early during application startup. Supply them through an appropriate environment variable, JVM system property, or command-line argument.

8. Using Spring Profiles for Environment-Specific Configuration

Profiles allow an application to use different configuration settings for different environments. A typical application might have development, testing, staging, and production environments.

Example File Structure

src/main/resources/
├── application.properties
├── application-dev.properties
├── application-test.properties
└── application-prod.properties

Development Configuration

# application-dev.properties
server.port=8081
logging.level.root=DEBUG

Production Configuration

# application-prod.properties
server.port=8080
logging.level.root=WARN

Activate a Profile

You can activate a profile with a command-line argument:

java -jar target/employee-management.jar \
  --spring.profiles.active=dev

You can also set the environment variable SPRING_PROFILES_ACTIVE to dev. Spring Boot then loads the configuration associated with that active profile along with the applicable default configuration.

Use profiles to manage legitimate differences between environments. Do not use them as a substitute for securely storing passwords, API keys, or other sensitive information.

9. Managing Sensitive Properties and Secrets

Externalized configuration helps separate secrets from application code. However, storing a password in an external file does not automatically make it secure. Access to the file, deployment environment, and secret storage system must also be controlled.

Example: Database Configuration

spring.datasource.url=${DB_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}

These placeholders refer to environment variables or other supported property sources. Ensure the variables are provided in the deployment environment and that the required database driver and data-access dependencies are present.

Security Best Practices

  • Never commit real production credentials to source control.
  • Use protected environment variables or a dedicated secrets-management service.
  • Restrict access to configuration files and deployment systems.
  • Use separate credentials for development, testing, and production.
  • Rotate credentials when required by security policy.
  • Avoid printing secrets in application logs or exception messages.
  • Do not assume that a property is secure simply because it is stored outside the Java source code.

10. Testing Externalized Configuration

Configuration should be tested to confirm that the application behaves correctly with the expected values. Spring Boot testing facilities allow tests to override configuration without changing the production configuration file.

Example Using @SpringBootTest

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest(properties = {
    "app.company.name=Test Company"
})
class ConfigurationTest {

    @Value("${app.company.name}")
    private String companyName;

    @Test
    void shouldLoadTestConfiguration() {
        assertEquals("Test Company", companyName);
    }
}

This test supplies a test-specific value and verifies that it can be injected into the Spring test context. The actual test class should be placed in the appropriate test source directory, and the project must include the relevant Spring Boot testing dependencies.

What Should Be Tested?

  • Required properties are present.
  • Configuration values bind to the expected Java types.
  • Profile-specific settings are applied correctly.
  • Invalid configuration is detected early where validation is configured.
  • Tests can override properties without modifying production configuration.
  • Secrets are not exposed in logs, test reports, or source control.

11. Troubleshooting Externalized Properties

Problem Possible Cause Solution
Property is not found Incorrect key, wrong file location, or missing configuration source. Check the key name and ensure the file is in a recognized location.
Unexpected property value A higher-priority property source overrides the file value. Inspect command-line arguments, system properties, environment variables, active profiles, and external files.
Profile settings are ignored The intended profile is not active or the filename is incorrect. Verify spring.profiles.active and the profile-specific filename.
Application fails due to a missing placeholder A required value was not supplied. Define the property or provide a suitable default if appropriate.
Configuration properties are not bound The properties class is not registered or the prefix does not match. Check the annotation, prefix, field names, and configuration-properties registration.
External file is not loaded The file is outside the configured search locations. Use a recognized location or configure spring.config.additional-location.
Application fails validation A configured value violates a declared constraint. Review the validation message and correct the supplied value.
Secret appears in logs Configuration values are being logged directly. Remove sensitive logging and review log access and retention policies.

12. Practical Project: Externalized Configuration for an Employee API

Objective: Create a Spring Boot application that reads configuration from external properties and supports environment-specific settings.

Step 1: Generate the Project

Open Spring Initializr, select Maven and Java, choose a compatible Spring Boot version, and add Spring Web.

Step 2: Configure application.properties

spring.application.name=employee-management
server.port=8082

app.company.name=ABC Technologies
app.company.location=Mumbai

Step 3: Create a Controller

package com.example.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CompanyController {

    @Value("${app.company.name}")
    private String companyName;

    @Value("${app.company.location}")
    private String location;

    @GetMapping("/company")
    public String getCompany() {
        return companyName + " is located in " + location;
    }
}

Step 4: Run the Application

# Windows
mvnw.cmd spring-boot:run

# macOS or Linux
./mvnw spring-boot:run

Step 5: Test the Endpoint

Open the following URL in a browser or API client:

http://localhost:8082/company

Expected response:

ABC Technologies is located in Mumbai

Step 6: Override a Property

Start the application with an overridden company name:

java -jar target/employee-management.jar \
  --app.company.name="Demo Technologies"

Use the actual generated JAR filename. The endpoint should reflect the supplied value when the application is launched with the override.

Step 7: Add Environment-Specific Settings

Create an application-dev.properties file, activate the dev profile, and verify that the development configuration is applied. Document the configuration sources used in the project.

13. Best Practices for Managing Externalized Properties

  • Use clear, consistent property names, preferably in lowercase kebab-case for custom configuration.
  • Use @ConfigurationProperties for related configuration values.
  • Use @Value for simple, isolated property injections.
  • Use profiles for environment-specific settings.
  • Understand property precedence before troubleshooting unexpected values.
  • Keep sensitive values in appropriately protected secret stores or deployment settings.
  • Validate required settings during application startup when practical.
  • Keep default configuration safe and suitable for local development.
  • Document external configuration requirements for deployment teams.
  • Test configuration behavior across supported environments.
  • Follow a consistent strategy for Properties and YAML files.
  • Consult the official Spring Boot documentation when using version-specific configuration features.

14. Interview Questions and Answers

Q1. What is externalized configuration?

Answer: It is the practice of maintaining application settings separately from application code so the same application can run with different settings in different environments.

Q2. Which configuration formats does Spring Boot support?

Answer: Spring Boot supports Java Properties files and YAML files, along with environment variables, system properties, command-line arguments, and other supported property sources.

Q3. What is the purpose of @Value?

Answer: It injects an individual configuration value into a Spring-managed bean using a property placeholder.

Q4. What is the advantage of @ConfigurationProperties?

Answer: It binds related properties into a structured Java object, supports type conversion, and can be combined with validation.

Q5. What are Spring profiles?

Answer: Profiles allow an application to activate environment-specific configuration and beans, such as settings for development or production.

Q6. How can you override a property at startup?

Answer: A property can be overridden using supported higher-priority sources, such as command-line arguments, environment variables, or Java system properties.

Q7. What is the difference between spring.config.location and spring.config.additional-location?

Answer: spring.config.location replaces the default configuration search locations, while spring.config.additional-location adds locations to the defaults.

Q8. Why should secrets be externalized?

Answer: Externalizing secrets reduces the risk of exposing credentials in source code, but the external storage and access permissions must still be secured.

Q9. How can configuration be tested?

Answer: Tests can supply dedicated property values through Spring Boot test annotations and verify that the application binds and uses those values correctly.

Q10. What should you do if a property has an unexpected value?

Answer: Inspect the active profiles and all relevant property sources, including external files, environment variables, system properties, and command-line arguments.

15. Quick Revision Checklist

  • Understand externalized configuration and its benefits.
  • Know the difference between Properties and YAML files.
  • Understand property sources and configuration precedence.
  • Know how to use @Value, Environment, and @ConfigurationProperties.
  • Understand how to activate Spring profiles.
  • Know how to load external configuration files.
  • Keep secrets outside source control and protect their storage.
  • Test configuration values and troubleshoot unexpected overrides.

16. Conclusion

Externalized properties are an essential part of building maintainable Spring Boot applications. They allow developers to separate settings from business logic, configure different environments, override values at deployment time, and organize configuration into structured Java objects.

By understanding property sources, precedence, profiles, external files, secret management, and configuration testing, developers can build applications that are easier to deploy, troubleshoot, and maintain.


Useful Learning Resources

Previous Next
whatsapp