不可变的@ConfigurationProperties

RJo*_*RJo 37 java spring properties-file spring-boot

是否可以使用Spring Boot的@ConfigurationProperties注释创建不可变(最终)字段?以下示例

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

  private final String neededProperty;

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

  public String getNeededProperty() { .. }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止我尝试过的方法:

  1. 创建@Bean了的MyProps两个类的构造函数
    • 提供两个构造函数:empty和with neededPropertyargument
    • bean是用.创建的 new MyProps()
    • 在该领域的结果 null
  2. 使用@ComponentScan@Component提供MyPropsbean.
    • 结果BeanInstantiationException- >NoSuchMethodException: MyProps.<init>()

我得到它的唯一方法是为每个非最终字段提供getter/setter.

Tom*_*Tom 12

我必须经常解决这个问题,并且我使用了一种不同的方法,这允许我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);
    }
}
Run Code Online (Sandbox Code Playgroud)

ApplicationProperties

@ConfigurationProperties(prefix = "myapp")
public class ApplicationProperties {

    private String someProperty;

    // ... other properties and getters

   public String getSomeProperty() {
       return someProperty;
   }
}
Run Code Online (Sandbox Code Playgroud)

还有一个具有最终属性的类

@Service
public class SomeImplementation implements SomeInterface {
    private final String someProperty;

    @Autowired
    public SomeImplementation(ApplicationProperties properties) {
        this.someProperty = properties.getSomeProperty();
    }

    // ... other methods / properties 
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢这种方法有很多不同的原因,例如,如果我必须在构造函数中设置更多属性,我的构造函数参数列表不是"巨大",因为我总是有一个参数(ApplicationProperties在我的例子中); 如果需要添加更多final属性,我的构造函数保持不变(只有一个参数) - 这可能会减少其他地方的更改次数等.

我希望这会有所帮助

  • 这只是使用@Value的很多锅炉板 (3认同)
  • 这是[tag:Java].更多样板意味着更好的代码 (3认同)

dav*_*xxx 5

从Spring Boot 2.2开始,最后可以定义用修饰的不可变类@ConfigurationProperties
该文档显示了一个示例。
您只需要声明一个带有绑定字段的构造函数(而不是setter方法)。
因此,您现在无需任何设置程序的实际代码就可以了:

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

  private final String neededProperty;

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

  public String getNeededProperty() { .. }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您现在必须使用“@ConstructorBinding”注释才能完成此操作。在此之前(RC1),您必须使用“@ImmutableConfigurationProperties”。有关为什么选择此注释的更多信息,您可以参考[issue 18563](https://github.com/spring-projects/spring-boot/issues/18563)。 (7认同)