The exact equivalent of the .NET Options Pattern in Spring Boot is @ConfigurationProperties.

Just like in .NET, it binds a group of related properties from your configuration file (application.properties or application.yml) to a strongly-typed Java class. It supports encapsulation, validation, dependency injection, and automatic refreshing.

Define the Configuration Section

Add a structured prefix section to your application.yml:

weather:
  city: "Trivandrum"
  temperature: 22
  enable-alerts: true
 

Create the Configuration Properties Class

Create a class (POCO/POJO counterpart) or a Java record. Using a record provides clean, immutable properties out of the box:

import org.springframework.boot.context.properties.ConfigurationProperties;
 
@ConfigurationProperties(prefix = "weather")
public record WeatherProperties(
    String city,
    int temperature,
    boolean enableAlerts
) {}
 

Enable Properties Scanning

Tell Spring Boot to look for classes annotated with @ConfigurationProperties. You can add this to your main application entry class:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
 
@SpringBootApplication
@ConfigurationPropertiesScan // Automatically finds and registers your properties classes
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Inject and Consume via Dependency Injection

Inject the configuration class directly into your controllers or components just like any other Spring Bean:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class WeatherController {
 
    private final WeatherProperties properties;
 
    // Injected directly via constructor injection
    public WeatherController(WeatherProperties properties) {
        this.properties = properties;
    }
 
    @GetMapping("/city")
    public String getCity() {
        return "Current city is " + properties.city();
    }
}
 

Replicating .NET Lifetimes (IOptionsSnapshot / Monitor)

In .NET, you switch between IOptions, IOptionsSnapshot, and IOptionsMonitor to handle dynamic reloads. In Spring Boot, configurations are Singletons by default (like IOptions). To achieve runtime configuration updates without restarting the application:

  1. Add Spring Cloud Context: Include the spring-cloud-starter-bootstrap dependency in your project.
  2. Apply @RefreshScope: Add this annotation alongside your @ConfigurationProperties bean.
  3. Trigger Updates: Call the /actuator/refresh endpoint to hot-reload values from external sources or files instantly at runtime.

Configuration Validation

Spring Boot mirrors .NET’s startup validation feature using standard Jakarta/Hibernate validation annotations.

  1. Add the dependencies for Validation to your build file (spring-boot-starter-validation).
  2. Add annotations and @Validated directly to the record/class:
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import org.springframework.validation.annotation.Validated;
 
@Validated
@ConfigurationProperties(prefix = "weather")
public record WeatherProperties(
    @NotBlank String city,
    @Min(-50) @Max(60) int temperature,
    boolean enableAlerts
) {}
 

If a user supplies an invalid value (e.g., a blank city or temperature 100), Spring Boot throws a ConfigurationPropertiesBindException and crashes application deployment immediately on startup, providing fail-fast security.