Spring BootJava 21Spring Framework深入淺出

Spring Boot 03: trace configuration, profiles, and overrides

··3 min read
Back to the Spring Boot learning path

You edit application.properties, restart, and still see an unexpected value. Before blaming caching, check command-line arguments, environment variables, and other configuration files. This lesson exposes the effective lab.label through /api/ping so the winning value is observable.

Bind configuration to one typed object

java
// LabProperties.java
package com.keeponfirst.bootlab;

import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

@Validated
@ConfigurationProperties(prefix = "lab")
public record LabProperties(@NotBlank String label,
                            @Min(1) @Max(200) int maxTitleLength) {}

The lab prefix maps label and max-title-length. LabApplication registers this record with @EnableConfigurationProperties so it can be injected. @Validated and the validation starter reject a blank label or a length limit outside 1–200 at startup. Conversion failures should also surface before business requests arrive.

@Value works for a small value; related settings fit a typed @ConfigurationProperties object. Here @Max(200) matches the table’s title capacity while the default business limit is 80. Changing a business setting without checking storage limits can move failures further down the request path.

properties
# application.properties
lab.label=boot-lab
lab.max-title-length=80

# application-local.properties
lab.label=local-profile

A profile selects configuration; it does not detect your environment

local is a name chosen for this example. Activating it loads the matching profile configuration; running in an office does not automatically select a corporate environment. Multiple profiles can be active, so real projects should record startup inputs and configuration sources rather than relying on names alone.

bash
java -jar target/boot-learning-lab-1.0.0.jar --spring.profiles.active=local
# Stop this process before starting the next one.
LAB_LABEL=from-env java -jar target/boot-learning-lab-1.0.0.jar --spring.profiles.active=local
# Stop again.
LAB_LABEL=from-env java -jar target/boot-learning-lab-1.0.0.jar --spring.profiles.active=local --lab.label=from-cli

With no additional sources, the three runs should return local-profile, from-env, and from-cli. For these sources, command-line arguments override environment variables, which override the configuration files. This is a subset of the full precedence rules; test properties and external configuration locations also matter.

Exercise: predict the final value

Predict the value with local profile, LAB_LABEL=A, and --lab.label=B, then verify with curl. Next start with --lab.max-title-length=0: validation should fail startup instead of silently returning to 80. If the observation differs, first check whether an old process is still answering.

Answer: B, with an explanation of its source

Knowing B is not enough: trace args into Boot’s configuration sources, through LabProperties binding and validation, and into the controller. That path transfers to diagnosing an unexpected URL or timeout in your work application.

Keep database passwords out of downloadable examples and committed files, and avoid dumping all settings into logs. An EAP-managed data source, listener, or pool has its own configuration owner; application.properties does not control every runtime setting.

Download the complete ticket API lab (ZIP)Next: 04: HTTP, validation, error contracts

Sources