Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/spring-projects/spring-boot/llms.txt

Use this file to discover all available pages before exploring further.

Spring Boot’s externalized configuration system lets you supply properties through command-line arguments, environment variables, application.properties, YAML files, and more — all merged in a well-defined precedence order. This guide answers the most common how-to questions around reading and customizing that configuration.
To set a property at startup, pass it as a command-line argument prefixed with --:
java -jar myapp.jar --server.port=9000
Command-line arguments always override file-based property sources. To disable this behavior, call SpringApplication.setAddCommandLineProperties(false).To set properties via environment variables, replace dots with underscores and uppercase the name. For example, server.port becomes SERVER_PORT.To supply multiple properties as a single JSON blob, use SPRING_APPLICATION_JSON:
SPRING_APPLICATION_JSON='{"my":{"name":"test"}}' java -jar myapp.jar
To set a property inside application.properties so it applies by default:
server.port=9000
spring.main.web-application-type=none
The same in YAML:
server:
  port: 9000
spring:
  main:
    web-application-type: "none"
Command-line properties take precedence over application.properties, which in turn overrides defaults set programmatically. See the full ordering in the Spring Boot reference documentation on externalized configuration.
To replace the default config file search with a specific file or directory, set spring.config.location before the application starts (as a system property, environment variable, or command-line argument — not inside application.properties):
java -jar myapp.jar --spring.config.location=optional:classpath:/default.properties,optional:classpath:/override.properties
To add locations on top of the defaults rather than replacing them, use spring.config.additional-location:
java -jar myapp.jar --spring.config.additional-location=optional:file:./custom-config/
Properties from additional locations override those in the default locations, so you can keep shared defaults in the jar and override them at runtime with an external file.To rename the config file from application to something else:
java -jar myproject.jar --spring.config.name=myproject
spring.config.name, spring.config.location, and spring.config.additional-location must be supplied as environment properties (OS variable, system property, or command-line argument). Setting them inside application.properties has no effect because the file has already been resolved.
To import additional files from inside application.properties:
spring:
  config:
    import: "optional:file:./dev.properties"
To use YAML, create application.yaml (or application.yml) at the root of your classpath. Spring Boot loads YAML automatically when SnakeYAML is on the classpath — it is included transitively by spring-boot-starter.YAML maps directly to flat property names. The following YAML:
spring:
  application:
    name: "cruncher"
  datasource:
    driver-class-name: "com.mysql.jdbc.Driver"
    url: "jdbc:mysql://localhost/test"
server:
  port: 9000
is equivalent to this application.properties:
spring.application.name=cruncher
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/test
server.port=9000
YAML also supports multi-document files, which lets you activate sections per profile:
server:
  port: 9000
---
spring:
  config:
    activate:
      on-profile: "development"
server:
  port: 9001
---
spring:
  config:
    activate:
      on-profile: "production"
server:
  port: 0
YAML files cannot be loaded with @PropertySource or @TestPropertySource. If you need to load values that way, use a .properties file instead.
Spring Boot does not include built-in property encryption, but it exposes EnvironmentPostProcessor as the integration point. Implement this interface to decrypt values before the application context starts:
@Order(Ordered.LOWEST_PRECEDENCE)
public class DecryptingEnvironmentPostProcessor implements EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment,
            SpringApplication application) {
        // Read encrypted values from the environment, decrypt, and re-add them
        // as a higher-priority PropertySource
    }
}
Register the implementation in META-INF/spring.factories:
org.springframework.boot.EnvironmentPostProcessor=com.example.DecryptingEnvironmentPostProcessor
For a production-grade solution, Spring Cloud Vault stores externalized configuration in HashiCorp Vault and integrates with Spring Boot’s Environment abstraction.
Use the optional: prefix on spring.config.import values when loading credentials from a vault or external store, so the application can still start when the external source is unavailable during local development.
Use @ConfigurationProperties when you have a group of related properties or hierarchical data. It provides relaxed binding, IDE metadata support, and type-safe structured objects:
@ConfigurationProperties(prefix = "my.service")
public class MyServiceProperties {
    private boolean enabled;
    private InetAddress remoteAddress;
    // getters and setters
}
Enable it on your main class or any @Configuration class:
@SpringBootApplication
@ConfigurationPropertiesScan
public class MyApplication { }
Use @Value for simple, single-value injection where SpEL expressions are needed:
@Value("${server.port:8080}")
private int port;
Key differences:
Feature@ConfigurationProperties@Value
Relaxed bindingYesLimited
IDE metadata supportYesNo
SpEL evaluationNoYes
Prefer @ConfigurationProperties for your own components. It produces cleaner, testable, and IDE-friendly configuration classes.
Spring Boot accepts multiple naming formats for the same property when binding to @ConfigurationProperties beans. For a property firstName on a class with prefix my.main-project.person, all of the following are equivalent:
Property nameFormat
my.main-project.person.first-nameKebab case (recommended for files)
my.main-project.person.firstNameCamel case
my.main-project.person.first_nameUnderscore notation
MY_MAINPROJECT_PERSON_FIRSTNAMEUpper case (recommended for env vars)
To convert a property name to an environment variable name:
  1. Replace dots (.) with underscores (_).
  2. Remove any dashes (-).
  3. Convert to uppercase.
For example, spring.main.log-startup-info becomes SPRING_MAIN_LOGSTARTUPINFO.
Relaxed binding applies to @ConfigurationProperties only. @Value supports a limited subset of this behavior. Always use kebab-case canonical form in @Value annotations (e.g., @Value("${demo.item-price}")) to get the broadest matching.
To express a Duration property, Spring Boot accepts three formats:
# All three are equivalent — 30 seconds
my.session-timeout=30
my.session-timeout=PT30S
my.session-timeout=30s
Supported duration units: ns, us, ms, s, m, h, d. The default unit is milliseconds unless you annotate the field with @DurationUnit.To express a DataSize property:
# Both are equivalent — 10 megabytes
my.buffer-size=10
my.buffer-size=10MB
Supported data size units: B, KB, MB, GB, TB. The default unit is bytes unless you annotate the field with @DataSizeUnit.Use these types in your @ConfigurationProperties class:
@ConfigurationProperties(prefix = "my")
public class MyProperties {
    @DurationUnit(ChronoUnit.SECONDS)
    private Duration sessionTimeout = Duration.ofSeconds(30);

    @DataSizeUnit(DataUnit.MEGABYTES)
    private DataSize bufferSize = DataSize.ofMegabytes(1);
    // getters and setters
}
To validate configuration properties at startup, annotate the class with @Validated and add JSR-303 constraint annotations to its fields:
@ConfigurationProperties(prefix = "my.service")
@Validated
public class MyServiceProperties {

    @NotNull
    private InetAddress remoteAddress;

    @Valid
    private final Security security = new Security();

    // getters and setters

    public static class Security {

        @NotEmpty
        private String username;
        // getters and setters
    }
}
Ensure a JSR-303 implementation is on the classpath (Hibernate Validator is included transitively by spring-boot-starter-validation):
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
If a constraint is violated, the application fails fast at startup with a clear error message rather than failing later at runtime.
Annotate nested properties classes with @Valid to cascade validation into them. Without @Valid, only the top-level fields are checked.
To embed build metadata (version, encoding, etc.) into your configuration files, use resource filtering.Maven: If you use spring-boot-starter-parent, reference Maven properties with @..@ placeholders:
app:
  encoding: "@project.build.sourceEncoding@"
  java:
    version: "@java.version@"
Without the starter parent, add this to your pom.xml:
<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
    </resource>
  </resources>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-resources-plugin</artifactId>
      <version>2.7</version>
      <configuration>
        <delimiters>
          <delimiter>@</delimiter>
        </delimiters>
        <useDefaultDelimiters>false</useDefaultDelimiters>
      </configuration>
    </plugin>
  </plugins>
</build>
Gradle: Configure the processResources task to expand project properties:
tasks.named('processResources') {
    expand(project.properties)
}
Then reference them in your config:
app:
  name: "${name}"
  description: "${description}"
Set useDefaultDelimiters=false in Maven to prevent the build from expanding Spring-style ${placeholder} expressions in your config files.

Build docs developers (and LLMs) love