Spring Boot Configuration: Properties, YAML, and Command-Line Arguments
This chapter explores how Spring Boot manages application configurations. We will examine how Spring Boot locates configuration files on the classpath, compare the syntax and structure of standard properties files with YAML files, analyze the priority and precedence rules when multiple configuration sources coexist, and demonstrate how to pass dynamic configuration parameters via command-line arguments and IDE run configurations.
1. The Classpath and Configuration Discovery
To understand how Spring Boot automatically finds configuration files like application.properties or application.yml, we must first understand the concept of the Classpath.
What is the Classpath?
The classpath is a dynamic list of directories and Java Archive (JAR) files that the Java Virtual Machine (JVM) searches to locate compiled .class files, external libraries, and resource files (such as images, XML files, and configuration files) during runtime.
How Spring Boot Locates Configuration Files
In a standard Maven-based Spring Boot project, the project structure separates source code from static resources:
During the build process, Maven compiles the Java classes and packages everything inside the src/main/resources directory directly into the root of the classpath.
Because Spring Boot is pre-configured to look at the root of the classpath for configuration files, it automatically discovers application.properties or application.yml inside src/main/resources without requiring any manual path registration.
Note: If you move your configuration files outside the standard classpath (externalizing configurations), you must explicitly provide the file path to the JVM using startup arguments (e.g.,
--spring.config.location=file:/path/to/config/).
2. Properties vs. YAML: Syntax and Structure
Spring Boot supports two primary file formats for externalized configuration: Properties and YAML.
The Properties Format (.properties)
The .properties format is the traditional Java configuration style. It uses a flat, key-value pair structure separated by an equals sign (=) or a colon (:).
- Syntax:
key=value - Characteristics: Flat hierarchy, repetitive prefix keys, and simple line-by-line parsing.
spring.data.mongodb.uri=mongodb://localhost:27017
spring.data.mongodb.database=journaldb
spring.data.mongodb.auto-index-creation=true
server.port=8081
server.servlet.context-path=/journal
The YAML Format (.yml or .yaml)
YAML is a recursive acronym for YAML Ain't Markup Language. Unlike XML or HTML, YAML does not rely on opening and closing tags. Instead, it uses a hierarchical, indentation-based structure that is highly human-readable.
- Syntax:
key: value(with nested indentation) - Characteristics: Uses spaces (typically 2 spaces) to define parent-child relationships, eliminates repetitive prefixes, and supports complex data structures like lists and maps.
3. Step-by-Step Evolution: Converting Properties to YAML
When a project grows, flat properties files can become verbose and difficult to maintain due to repetitive prefixes (e.g., repeating spring.data.mongodb for every property). Converting these configurations to YAML cleans up the structure.
Naive Properties Configuration
spring.data.mongodb.uri=mongodb://localhost:27017/journaldb
spring.data.mongodb.database=journaldb
spring.data.mongodb.auto-index-creation=true
server.port=8081
server.servlet.context-path=/journal
Clean Nested YAML Configuration
To convert the properties above into YAML, group common prefixes into nested blocks using indentation.
spring:
data:
mongodb:
uri: mongodb://localhost:27017/journaldb
database: journaldb
auto-index-creation: true
server:
port: 8081
servlet:
context-path: /journal
Key YAML Formatting Rules
- Indentation Matters: Always use spaces (typically 2 spaces per indentation level) to indicate hierarchy. Do not mix tabs and spaces, as this can cause parsing errors.
- Colon Followed by Space: There must always be a space after the colon separating the key and the value (e.g.,
port: 8081, notport:8081). - No Duplicate Parent Keys: Group all child properties under a single parent key block rather than declaring the parent key multiple times.
4. Configuring Server Port and Context Path
By default, an embedded Tomcat server in Spring Boot starts on port 8080 with a root context path (/). You can customize these settings to run multiple applications on the same machine or to group APIs under a specific base path.
1. Server Port (server.port)
Specifies the network port on which the embedded web server listens.
- Default:
8080 - Customized:
8081
2. Context Path (server.servlet.context-path)
Specifies the prefix path that must be appended to all incoming HTTP request URLs.
- Default:
/(Root) - Customized:
/journal
Request Routing Workflow Comparison
Default Configuration (Port: 8080, Context Path: /)
Customized Configuration (Port: 8081, Context Path: /journal)
If you attempt to access http://localhost:8081/entry without the /journal context path, the server will return a 404 Not Found error.
5. Building and Running via Command Line
In a production environment, applications are built into executable JAR files and run from the command line. We can use the Maven Wrapper (mvnw) to build and package the application without needing a global Maven installation.
Step 1: Clean the Target Directory
To remove previous build artifacts and the target folder, run:
# On Linux / macOS
./mvnw clean
# On Windows Command Prompt
mvnw.cmd clean
Step 2: Package the Application
To compile the code, run tests, and package the application into an executable JAR file:
# On Linux / macOS
./mvnw package
# On Windows Command Prompt
mvnw.cmd package
This command generates a JAR file inside the target/ directory (e.g., target/journalApp-0.0.1-SNAPSHOT.jar).
Step 3: Run the Executable JAR
To run the packaged Spring Boot application using the JVM:
java -jar target/journalApp-0.0.1-SNAPSHOT.jar
6. Configuration Precedence & Priority Order
Spring Boot allows you to define properties in multiple locations. When the same property is defined in more than one place, Spring Boot resolves the conflict using a strict hierarchy of precedence.
The Precedence Hierarchy (Highest to Lowest)
Detailed Precedence Comparison
Real-World Conflict Scenario
If your application contains the following configurations:
application.ymldefinesserver.port=8082application.propertiesdefinesserver.port=8081- You start the application using:
BASH
java -jar app.jar --server.port=9090
Result: The application will start on port 9090 because command-line arguments take absolute precedence. If you stop the application and run it without command-line arguments, it will start on port 8081 (overriding the YAML file).
7. Passing Arguments via IDE (IntelliJ IDEA)
During development, you can simulate command-line arguments directly within your IDE without packaging the application into a JAR every time.
How to Configure Program Arguments in IntelliJ IDEA:
- In the top-right corner of IntelliJ, click on the Run/Debug Configurations dropdown menu next to the run button.
- Select Edit Configurations...
- Select your Spring Boot main application class (e.g.,
JournalApplication). - Locate the Program arguments input field.
- Enter your override arguments using the double-dash (
--) prefix:BASH--server.port=9092 --server.servlet.context-path=/api - Click Apply and then OK.
- Run the application. The IDE will append these arguments to the execution command, starting the application on port
9092with the/apicontext path.
8. Summary and Key Takeaways
- Classpath Auto-Discovery: Spring Boot automatically scans the root of the classpath (such as
src/main/resources) to find and loadapplication.propertiesorapplication.yml. - Properties vs. YAML: Properties files use a flat
key=valuestructure, whereas YAML files use a clean, nested, indentation-based hierarchy that reduces repetitive prefixes. - YAML Indentation Rule: YAML relies strictly on spaces for indentation. Mixing tabs and spaces or omitting the space after a colon (
:) will cause parsing errors. - Context Path Customization: The
server.servlet.context-pathproperty adds a base prefix to all application URLs, which is useful for API versioning and routing. - Maven Wrapper Utility: The Maven Wrapper (
./mvnwormvnw.cmd) allows you to clean, compile, and package your application into an executable JAR without requiring a pre-installed Maven instance on the host machine. - Strict Precedence Order: Spring Boot resolves configuration conflicts in a strict order: Command-Line Arguments >
application.properties>application.yml. - Production Flexibility: Externalizing configurations via command-line arguments allows DevOps engineers to deploy the same compiled JAR across different environments (Development, QA, Production) simply by changing the startup arguments.