对Spring ConfigurationProperties子类使用构造函数注入 [英] Use constructor injection for spring ConfigurationProperties subclasses

查看:509
本文介绍了对Spring ConfigurationProperties子类使用构造函数注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查看此 https://www.baeldung.com/



对于是否可以使用构造函数注入来强制实施某些不变性属性。



例如,可以这样做:

  @Component 
@ConfigurationProperties( my-config)
公共类MyConfig {

private final List< String>价值观

public MyConfig(@Value( $ {values})List< String>值){
this.values = ImmutableList.copyOf(values);
}
}

然后在我的yml配置中有

  my-config.values:
-foo
-bar

但我收到此错误:

  java.lang .IllegalArgumentException:无法解析字符串值 $ {values}中的占位符 values 


方案

文档状态:


属性值可以通过以下方式直接注入到您的bean中:使用通过Spring的环境抽象访问的
@Value批注,可以将
通过@ConfigurationProperties绑定到结构化对象。


您实际上尝试混合其行为。

不是Spring环境的属性,而是 my-config.values 是。

甚至在<$ c $内部声明c> MyConfig ,例如 @Value( $ {values}) ,它不会更改 @ConfigurationProperties 将属性绑定到结构化对象。当然,它不会在Spring环境中创建新属性,这就是 @Value()寻找解析值表达式的地方。

而解决 $ {values} 的异常。



作为 MyConfig 是组件 @Value 应该是您所需要的:

  @Component 
公共类MyConfig {

private final List< String>价值观

public MyConfig(@Value( $ {my-config.values})List< String>值){
this.values = ImmutableList.copyOf(values);
}
}

您也可以通过保护设置器来防止可变性进行检查,但这只会在运行时检测到问题:

  @ConfigurationProperties( my-config)
public class MyConfig {

private final List< String>价值观

公共列表< String> getValue(){
返回值;
}
public void setValue(List< String> values){
if(this.values!= null){
throw new IllegalArgumentException( ...);
}
this.values = ImmutableList.copyOf(values);
}
}


I was looking at this https://www.baeldung.com/configuration-properties-in-spring-boot and was wondering if it was possible to use constructor injection for these in order to enforce some immutability properties.

For example would it be possible to do this:

@Component
@ConfigurationProperties("my-config")
public class MyConfig {

    private final List<String> values;

    public MyConfig(@Value("${values}") List<String> values) {
        this.values = ImmutableList.copyOf(values);
    }
}

And then in my yml config have

my-config.values:
  - foo
  - bar

But I get this error:

java.lang.IllegalArgumentException: Could not resolve placeholder 'values' in string value "${values}"

解决方案

The documentation states :

Property values can be injected directly into your beans by using the @Value annotation, accessed through Spring’s Environment abstraction, or be bound to structured objects through @ConfigurationProperties. :

You actually try to mix their behavior.
values is not a property of the Spring environment but my-config.values is.
Even declared inside MyConfig such as @Value("${values})" it doesn't change anything as @ConfigurationProperties bounds the properties to a structured object. And of course it doesn't create new properties in the Spring environment, that is where @Value() looks for to resolve the value expression.
Whereas the exception to resolve ${values}.

As MyConfig is a component @Value should be what you need :

@Component
public class MyConfig {

    private final List<String> values;

    public MyConfig(@Value("${my-config.values}") List<String> values) {
        this.values = ImmutableList.copyOf(values);
    }
}

You could also prevent the mutability by protecting the setter with a check but this will detect the issue only at runtime :

@ConfigurationProperties("my-config")
public class MyConfig {

    private final List<String> values;

    public List<String> getValue(){
         return values;
    }
    public void setValue(List<String> values){  
         if (this.values != null){
             throw new IllegalArgumentException("...");
         }                    
         this.values = ImmutableList.copyOf(values);
    }
}

这篇关于对Spring ConfigurationProperties子类使用构造函数注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆