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.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Optimizing Spring Boot Configuration with @ConfigurationProperties and Java Records

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: http

Injecting 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Backend Developmentvalidationspring-bootconfigurationpropertiesJava RecordsImmutable Configuration
Spring Full-Stack Practical Cases
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.