Issue
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:
- Creating a
@Bean
of theMyProps
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
- Providing two constructors: empty and with
- Using
@ComponentScan
and@Component
to provide theMyProps
bean.- Results in
BeanInstantiationException
->NoSuchMethodException: MyProps.<init>()
- Results in
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() { .. }
}
Answered By - davidxxx
Answer Checked By - Senaida (JavaFixing Volunteer)