当属性不存在时,Spring @Value注释不使用默认值

时间:2011-01-15 07:49:02

标签: java spring annotations

我试图在构造函数的参数中使用@Value注释,如下所示:

@Autowired
public StringEncryptor(
    @Value("${encryptor.password:\"\"}") String password,
    @Value("${encryptor.algorithm:\"PBEWithMD5AndTripleDES\"}") String algorithm,
    @Value("${encryptor.poolSize:10}") Integer poolSize, 
    @Value("${encryptor.salt:\"\"}") String salt) {
...
}

当类路径中存在属性文件时,属性将完美加载并且测试执行正常。但是,当我从类路径中删除属性文件时,我原本期望使用默认值,例如poolSize将设置为10或算法设置为PBEWithMD5AndTripleDES但是情况并非如此。

通过调试器运行代码(仅在将@Value("${encryptor.poolSize:10}") Integer poolSize更改为@Value("${encryptor.poolSize:10}") String poolSize时才会起作用,因为它导致NumberFormatExceptions)我发现默认值没有设置,参数是以:

poolSize = ${encryptor.poolSize:10}

algorithm = ${encryptor.algorithm:"PBEWithMD5AndTripleDES"}

而不是预期的

poolSize = 10

algorithm = "PBEWithMD5AndTripleDES"

基于SPR-4785,$ {my.property:myDefaultValue}等符号应该有效。但它并没有发生在我身上!

谢谢

3 个答案:

答案 0 :(得分:22)

由于遗漏属性文件,属性占位符配置器的初始化可能会失败,因此不会解析占位符。您可以将其配置为忽略丢失的文件,如下所示(如果使用context命名空间进行配置):

<context:property-placeholder ignore-resource-not-found="true" ... />

此外,您不需要"..."左右默认值。

答案 1 :(得分:6)

ignore-resource-not-found =“true”不需要拾取默认值。如果在任何地方找不到属性,则指定默认值的点是使用它。

我认为上一个答案中的最后一句话指的是问题 - 您必须最初提供的错误的EL,但随后从示例中删除了。您获得格式转换异常的事实也指向了这一点。通常,Spring会自动将字符串转换为适当的“标准”Java类型,如果您提供自己的Spring转换服务实现,也可以自定义您的自定义对象 - 只要您的转换服务在应用程序上下文中定义。 / p> 当您通过XML注入属性而没有默认值时,“ignore-resource-not-found”非常有用,并且如果没有找到属性,则不希望容器抛出实例化bean的异常。在这种情况下,bean属性将使用Java默认值进行初始化,例如:对象为null,原始数值为0,等等。

答案 2 :(得分:2)

在我的情况下,解析属性值(和默认值)在测试中不起作用,我使用基于注释的配置。事实证明,我必须添加一个PropertySourcesPlaceholderConfigurer,以便实际解析属性。在PropertySource Annotation JavaDoc

中对此进行了解释
  

为了使用PropertySource中的属性解析定义中的$ {...}占位符或@Value注释,必须注册PropertySourcesPlaceholderConfigurer 。在XML中使用时会自动发生这种情况,但在使用@Configuration类时必须使用静态@Bean方法显式注册。有关详细信息和示例,请参阅@Configuration Javadoc的“使用外部化值”部分和@Bean Javadoc的“关于BeanFactoryPostProcessor返回@Bean方法的说明”。

以下是诀窍:

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}

如果你想添加个别属性:

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {

    PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();

    Properties properties = new Properties();
    properties.put("batchSize", "250");
    propertySourcesPlaceholderConfigurer.setProperties(properties);

    return propertySourcesPlaceholderConfigurer;
}