是否可以使用Sping Boot 的@ConfigurationProperties
注解来拥有不可变(final)字段?下面的例子
@ConfigurationProperties(prefix = "example")
public final class MyProps {
private final String neededProperty;
public MyProps(String neededProperty) {
this.neededProperty = neededProperty;
}
public String getNeededProperty() { .. }
}
到目前为止我尝试过的方法:
- 使用两个构造函数创建
MyProps
类的@Bean
- 提供两个构造函数:空且带有
neededProperty
参数 - 使用
new MyProps()
创建bean - 字段中的结果为
null
- 使用
@ComponentScan
和@Component
提供MyProps
bean。 - 结果为
BeanInstantiationException
->NoSuchMethodException: MyProps.<init>()
我让它工作的唯一方法是为每个非final字段提供getter/setter。
9条答案
按热度按时间nzk0hqpo1#
从Sping Boot 2.2开始,终于可以定义一个用
@ConfigurationProperties
修饰的不可变类。文档显示了一个示例。
您只需要声明一个带有要绑定的字段的构造函数(而不是setter方法),并在类级别添加
@ConstructorBinding
注解以指示应使用构造函数绑定。因此,没有任何setter的实际代码现在很好:
jmp7cifd2#
我经常需要解决这个问题,所以我使用了一种不同的方法,它允许我在类中使用
final
变量。首先,我将所有配置保存在一个单独的地方(类),比如称为
ApplicationProperties
。该类具有带特定前缀的@ConfigurationProperties
注解。它也被列在@EnableConfigurationProperties
注解中的配置类(或主类)。然后,我提供
ApplicationProperties
作为构造函数参数,并在构造函数中对final
字段执行赋值。示例:
主类:
**
ApplicationProperties
**类和具有final属性的类
我喜欢这种方法有很多不同的原因,例如。如果我必须在构造函数中设置更多的属性,我的构造函数参数列表并不“庞大”,因为我总是有一个参数(在我的例子中是
ApplicationProperties
);如果需要添加更多的final
属性,我的构造函数保持不变(只有一个参数)-这可能会减少其他地方的更改数量等。我希望那会有帮助
camsedfj3#
使用与https://stackoverflow.com/a/60442151/11770752类似的方法
但是你可以使用
RequiredArgsConstructor
来代替AllArgsConstructor
。考虑以下
applications.properties
fistName
和last-name
).Java类提取属性
此外,您还必须向构建工具添加依赖项。
或
如果您更进一步地为您的配置提供漂亮而精确的描述,请考虑在目录
src/main/resources/META-INF
中创建一个文件additional-spring-configuration-metadata.json
。(clean & compile to take effect)
至少在IntelliJ中,当您将鼠标悬停在
application.propoerties
中的属性上时,您可以清楚地看到自定义属性的描述。对其他开发人员非常有用。这给了我一个很好的和简洁的属性结构,我正在使用我的服务与Spring。
xxls0lw84#
最后,如果你想要一个不可变的对象,你也可以“破解”setter
显然,如果属性不只是一个字符串,而是一个可变对象,事情会更复杂,但那是另一回事。
更好的是,您可以创建一个配置容器
现在的配置是一个类,没有
和application.yml作为
kq0g1dla5#
我的想法是通过内部类封装属性组,并仅使用getter公开接口。
属性文件:
代码:
lstz6jyr6#
只是对最新Spring-Boot版本的最新支持的更新:
如果你使用的是>= 14的jdk版本,你可以使用
record
类型,它或多或少与Lombok版本相同,但没有Lombok。您还可以在
MyProps
记录中使用record来管理嵌套属性。你可以看到一个例子here。另一个有趣的帖子here表明,如果只声明一个构造函数,
@ConstructorBinding
注解甚至不再必要。muk1a3rh7#
使用Lombok注解,代码看起来像这样:
此外,如果您想直接自动连接此属性类,而不使用
@Configuration
类和@EnableConfigurationProperties
,则需要将@ConfigurationPropertiesScan
添加到使用@SpringBootApplication
注解的主应用程序类。请参阅此处的相关文档:https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-constructor-binding
xe55xuns8#
如果你想在不加载整个spring Boot 上下文的情况下在你的应用程序中切片测试你的属性,在你的测试中使用
@EnableConfigurationProperties
。示例:
src/main/resources/application.yml
f2uvfpb99#
您可以通过
@Value
注解设置字段值。这些可以直接放置在字段上,不需要任何设置器:这种方法的缺点是: