是否可以使用Spring的@ConfigurationProperties注释拥有不可变(最终)字段?下面的例子
@ConfigurationProperties(prefix = "example")
public final class MyProps {
private final String neededProperty;
public MyProps(String neededProperty) {
this.neededProperty = neededProperty;
}
public String getNeededProperty() { .. }
}到目前为止我尝试过的方法:
@Bean创建MyProps类的neededProperty参数new MyProps()创建的。null
@ComponentScan和@Component提供MyProps bean。BeanInstantiationException -> NoSuchMethodException: MyProps.<init>()中的结果
我让它工作的唯一方法是为每个非最终字段提供getter/setter。
发布于 2019-07-24 21:09:01
从SpringBoot2.2开始,最终可以定义一个用@ConfigurationProperties修饰的不可变类。
文献资料给出了一个例子。
您只需要使用要绑定的字段(而不是setter方式)声明构造函数,并在类级别添加@ConstructorBinding注释,以指示应该使用构造函数绑定。
因此,没有任何setter的实际代码现在可以了:
@ConstructorBinding
@ConfigurationProperties(prefix = "example")
public final class MyProps {
private final String neededProperty;
public MyProps(String neededProperty) {
this.neededProperty = neededProperty;
}
public String getNeededProperty() { .. }
}发布于 2015-02-27 11:29:49
我必须经常解决这个问题,我使用了一种稍微不同的方法,它允许我在类中使用final变量。
首先,我将所有配置保存在一个地方(类)中,例如,称为ApplicationProperties。该类具有带有特定前缀的@ConfigurationProperties注释。它还在针对配置类(或主类)的@EnableConfigurationProperties注释中列出。
然后,我提供我的ApplicationProperties作为构造函数参数,并对构造函数中的final字段执行赋值。
示例:
主类:
@SpringBootApplication
@EnableConfigurationProperties(ApplicationProperties.class)
public class Application {
public static void main(String... args) throws Exception {
SpringApplication.run(Application.class, args);
}
}ApplicationProperties类
@ConfigurationProperties(prefix = "myapp")
public class ApplicationProperties {
private String someProperty;
// ... other properties and getters
public String getSomeProperty() {
return someProperty;
}
}和一个具有最终性质的类
@Service
public class SomeImplementation implements SomeInterface {
private final String someProperty;
@Autowired
public SomeImplementation(ApplicationProperties properties) {
this.someProperty = properties.getSomeProperty();
}
// ... other methods / properties
}由于许多不同的原因,我更喜欢这种方法,例如,如果我必须在构造函数中设置更多的属性,构造函数参数的列表并不是“巨大的”,因为我总是有一个参数(在我的例子中是ApplicationProperties);如果需要添加更多的final属性,那么构造函数保持不变(只有一个参数)--这可能会减少其他地方更改的数量等等。
我希望这能帮上忙
发布于 2018-04-10 10:20:05
最后,如果您想要一个不可变的对象,您也可以“黑”到
@ConfigurationProperties(prefix = "myapp")
public class ApplicationProperties {
private String someProperty;
// ... other properties and getters
public String getSomeProperty() {
return someProperty;
}
public String setSomeProperty(String someProperty) {
if (someProperty == null) {
this.someProperty = someProperty;
}
}
}显然,如果属性不仅仅是一个字符串,即一个可变的对象,那么事情就更复杂了,但这是另一个故事。
更好的是,您可以创建配置容器。
@ConfigurationProperties(prefix = "myapp")
public class ApplicationProperties {
private final List<MyConfiguration> configurations = new ArrayList<>();
public List<MyConfiguration> getConfigurations() {
return configurations
}
}现在的配置是一个没有
public class MyConfiguration {
private String someProperty;
// ... other properties and getters
public String getSomeProperty() {
return someProperty;
}
public String setSomeProperty(String someProperty) {
if (this.someProperty == null) {
this.someProperty = someProperty;
}
}
}和application.yml作为
myapp:
configurations:
- someProperty: one
- someProperty: two
- someProperty: otherhttps://stackoverflow.com/questions/26137932
复制相似问题