javaspringspring-bootproperties-file

Immutable @ConfigurationProperties


Is it possible to have immutable (final) fields with Spring Boot's @ConfigurationProperties annotation? Example below

@ConfigurationProperties(prefix = "example")
public final class MyProps {

  private final String neededProperty;

  public MyProps(String neededProperty) {
    this.neededProperty = neededProperty;
  }

  public String getNeededProperty() { .. }
}

Approaches I've tried so far:

  1. Creating a @Bean of the MyProps class with two constructors
    • Providing two constructors: empty and with neededProperty argument
    • The bean is created with new MyProps()
    • Results in the field being null
  2. Using @ComponentScan and @Component to provide the MyProps bean.
    • Results in BeanInstantiationException -> NoSuchMethodException: MyProps.<init>()

The only way I have got it working is by providing getter/setter for each non-final field.


Solution

  • From Spring Boot 2.2, it is at last possible to define an immutable class decorated with @ConfigurationProperties.
    The documentation shows an example.
    You just need to declare a constructor with the fields to bind (instead of the setter way) and to add the @ConstructorBinding annotation at the class level to indicate that constructor binding should be used.
    So your actual code without any setter is now fine :

    @ConstructorBinding
    @ConfigurationProperties(prefix = "example")
    public final class MyProps {
    
      private final String neededProperty;
    
      public MyProps(String neededProperty) {
        this.neededProperty = neededProperty;
      }
    
      public String getNeededProperty() { .. }
    }