【问题标题】:Evaluating Spring @Value annotation as primitive boolean将 Spring @Value 注释评估为原始布尔值
【发布时间】:2012-11-27 13:25:51
【问题描述】:

我有一个 Spring @Configuration 注释类 MappingsClientConfig,其布尔字段为:

 @Value("${mappings.enabled:true}")
 private boolean mappingsEnabled;

这个类被导入到另一个 Spring 注释类中,如下所示:

@Configuration
@Import(MappingsClientConfig.class)
public class LookupManagerConfig {

在测试用例中通过 Spring 上下文实例化类时,容器无法将字符串解析为布尔字段 mappingsEnabled,我得到:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private boolean com.barcap.tcw.mappings.economic.client.config.EconomicMappingsClientConfig.economicMappingsEnabled; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [${mappings.enabled:true}]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
    ... 138 more
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [${mappings.enabled:true}]
    at org.springframework.beans.SimpleTypeConverter.convertIfNecessary(SimpleTypeConverter.java:61)
    at org.springframework.beans.SimpleTypeConverter.convertIfNecessary(SimpleTypeConverter.java:43)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:718)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
    ... 140 more
Caused by: java.lang.IllegalArgumentException: Invalid boolean value [${mappings.enabled:true}]
    at org.springframework.beans.propertyeditors.CustomBooleanEditor.setAsText(CustomBooleanEditor.java:124)
    at org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.java:416)
    at org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.java:388)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:157)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:93)
    at org.springframework.beans.SimpleTypeConverter.convertIfNecessary(SimpleTypeConverter.java:49)
    ... 144 more

关于我缺少什么的任何线索?

【问题讨论】:

  • 我认为问题是由于您没有加载定义 mappings.enabled 的属性文件,但没有更多细节我无法确定。

标签: spring annotations


【解决方案1】:

这是一个旧线程,但如果您仍想使用 @Value Spring 注解注入非字符串值,请执行以下操作:

@Value("#{new Boolean('${item.priceFactor}')}")
private Boolean itemFactorBoolean;

@Value("#{new Integer('${item.priceFactor}')}")
private Integer itemFactorInteger;

在 Spring boot 1.5.9 和 Java 8 上为我工作。

【讨论】:

  • spring 4.3 在 中有 setTrimValues()。对于 spring "xx = true " 变为 false。 @Value("#{new Boolean('${xx}'.trim())}")
  • 也适用于 Spring Boot 2.x。
【解决方案2】:

看起来您缺少 PropertyPlaceholderConfigurer。您需要将其注册为 bean factory 后处理器。理论上可以这样做:

public class PostProcessorConfig {

    @Bean
    public BeanFactoryPostProcessor getPP() {
       PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
       configurer.setLocations(new Resource[]{new ClassPathResource("/my.properties")});
       return configurer;
    }
}

但是,似乎有一个bug 会导致其他问题从基于 java 的配置中执行此操作。请参阅票证以了解解决方法。

【讨论】:

  • 添加 PropertyPlaceholderConfigurer 就可以了。但最初,当我尝试定义一个新的 PropertyPlaceholderConfigurer 时,我收到了之前工作正常的丢失占位符的错误。好像定义新的 PropertyPlaceholderConfigurer 覆盖了一些现有的行为。所以现在,我已经定义了一个新的 PPC 并将我的所有属性添加到由它加载的单个属性文件中。但问题仍然是这些属性是从哪里加载的?
【解决方案3】:

这就是我们项目中的解决方法,因为其他答案对我们不起作用。我们也在使用 Spring Batch。

主要工作配置:

@Configuration
@EnableBatchProcessing
@PropertySource("classpath:application.properties")
public class MainJobConfiguration {
    @Autowired
    PipelineConfig config;

    @Bean
    public PipelineConfig pipelineConfig(){
        return new PipelineConfig();
    }

    // To resolve ${} in @Value
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    // job stuff ...
}

属性配置加载器:

public class PipelineConfig {
    @Value("${option}")
    private boolean option;
}

请注意 @Value 在 PipelineConfig 中的位置,但加载选项的实际属性是在作业类中指定的。

【讨论】:

    【解决方案4】:

    你甚至不需要属性文件,例如:

    【讨论】:

    • 你能澄清一下这条线在哪里吗?在 LookupManagerConfig 的 xml 中?如果我理解的很好,是否相当于在LookupManagerConfig中添加@Autowired PropertyPlaceholderConfigurer configurer;来使用java config?
    • @jmmut 显然是 applicationContext.xml !
    猜你喜欢
    • 2011-05-07
    • 2011-07-13
    • 2011-07-31
    • 2012-11-22
    • 2018-03-10
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 2011-08-28
    相关资源
    最近更新 更多