Optimizing Spring Boot Configuration with @ConfigurationProperties and Java Records
This article demonstrates how to combine Spring Boot's @ConfigurationProperties with Java records to create concise, immutable, and type‑safe configuration classes, covering scanning setup, record definition, YAML binding, constructor injection, validation with @Validated, and best‑practice recommendations for managing configuration in Spring Boot 3.5.0.
In Java development, reducing boilerplate code and improving maintainability are key goals. Spring Boot offers the @ConfigurationProperties annotation to externalize configuration, while Java 16 introduced records as a concise way to model immutable data. Combining these two features can greatly simplify application setup.
Benefits of using records with @ConfigurationProperties
Reduced boilerplate: records automatically generate constructors, getters, equals(), hashCode(), and toString().
Immutable configuration: records are inherently immutable, making them ideal for configuration objects whose values should not change at runtime.
Type‑safe binding: @ConfigurationProperties binds external configuration to strongly‑typed Java classes, enhancing type safety and reducing errors.
Enabling configuration scanning
To detect classes annotated with @ConfigurationProperties, add @ConfigurationPropertiesScan with the target package to the main application class:
@SpringBootApplication
@ConfigurationPropertiesScan("com.pack.config")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}Defining a record configuration class
@ConfigurationProperties(prefix = "pack.server.config")
public record ServerProperties(
int port,
String host,
Security security) {
public record Security(boolean enabled, String protocol) {}
}The corresponding application.yml (or .properties) file looks like:
pack:
server:
config:
host: 127.0.0.1
port: 6666
security:
enabled: true
protocol: httpInjecting the record
@Component
public class RecordRunner implements CommandLineRunner {
private final ServerProperties serverProperties;
public RecordRunner(ServerProperties serverProperties) {
this.serverProperties = serverProperties;
}
@Override
public void run(String... args) throws Exception {
System.err.println(this.serverProperties);
}
}Running the application prints:
ServerProperties[port=6666, host=127.0.0.1, security=Security[enabled=true, protocol=http]]Validation
Add @Validated to the record class and use Bean Validation annotations such as @Min or @NotEmpty on fields:
@ConfigurationProperties(prefix = "pack.server.config")
@Validated
public record ServerProperties(
@Min(value = 8000, message = "Port cannot be less than 8000") int port,
String host,
Security security) {
public record Security(boolean enabled, String protocol) {}
}When the application starts with an invalid port, Spring throws a validation error. To enable validation, include the spring-boot-starter-validation dependency.
Best practices
Keep configuration records simple; they should only contain data, not business logic.
Perform necessary validation using Bean Validation annotations.
Use @ConfigurationPropertiesScan to scan multiple packages, or register specific classes with @EnableConfigurationProperties.
Alternatively, annotate a record with @Component and @ConfigurationProperties to make it a Spring bean directly.
These guidelines help you manage configuration cleanly and safely in Spring Boot 3.5.0.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
