Spring Boot 03: trace configuration, profiles, and overrides
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
// 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.
# application.properties
lab.label=boot-lab
lab.max-title-length=80
# application-local.properties
lab.label=local-profileA 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.
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-cliWith 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