Spring @PropertySource和环境类型转换

时间:2013-11-28 15:23:46

标签: spring type-conversion spring-annotations

我使用PropertyPlaceholderConfigurer创建了一个基于xml的弹簧配置,如下所示:

  <context:property-placeholder location="classpath:my.properties" />

  <bean id="myBean" class="com.whatever.TestBean">
    <property name="someValue" value="${myProps.value}" />
  </bean>

其中myprops.value=classpath:configFile.xml和'someValue'属性的setter接受 org.springframework.core.io.Resource

这很好用 - PPC会自动在字符串值和资源之间进行转换。

我现在正在尝试使用Java Config和@PropertySource注释,如下所示:

@Configuration
@PropertySource("classpath:my.properties")
public class TestConfig {

    @Autowired Environment environment;

    @Bean
    public TestBean testBean() throws Exception {
        TestBean testBean = new TestBean();
        testBean.setSomeValue(environment.getProperty("myProps.value", Resource.class));
        return testBean;
    }

}

Spring Environment类的getProperty()方法提供了一个重载来支持我使用的不同类型的转换,但是默认情况下这并不支持将属性转换为Resource:

Caused by: java.lang.IllegalArgumentException: Cannot convert value [classpath:configFile.xml] from source type [String] to target type [Resource]
    at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:81)
    at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:370)
    at config.TestConfig.testBean(TestConfig.java:19)

查看底层源代码,Environment实现使用PropertySourcesPropertyResolver,后者又使用DefaultConversionService,这只注册非常基本的转换器。

所以我有两个问题:
1)我如何才能支持转换为资源?
2)为什么我需要在原始PPC为我做这个时?

2 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,事实证明,context:property-placeholder不仅加载了属性文件,而且还声明了处理所有文件的特殊bean org.springframework.context.support.PropertySourcesPlaceholderConfigurer,例如解析${...}属性并替换它们。

要修复它,您只需创建其实例:

@Configuration
public class TestConfig {

    @Autowired Environment environment;

    @Bean 
    public static PropertySourcesPlaceholderConfigurer configurer (){ 
         PropertySourcesPlaceholderConfigurer postProcessor = new PropertySourcesPlaceholderConfigurer();
         postProcessor.setLocation(new ClassPathResource("my.properties"));
         return postProcessor; 
    } 

...

请注意,您需要删除@PropertySource("classpath:my.properties")注释。

答案 1 :(得分:0)

我已经解决了这个问题。

我已经意识到从资源包中获取属性然后在bean上设置属性之间存在区别 - Spring将使用相关的PropertyEditor(ResourceEditor)设置属性时进行转换。所以我们必须手动完成这一步:

@Configuration
@PropertySource("classpath:my.properties")
public class TestConfig {

    @Autowired Environment environment;

    @Bean
    public TestBean testBean() throws Exception {
        ResourceEditor editor = new ResourceEditor();
        editor.setAsText(environment.getProperty("myProps.value"));
        TestBean testBean = new TestBean();
        testBean.setSomeValue((Resource)editor.getValue());
        return testBean;
    }

}

然而,这确实留下了一个突出的问题:为什么Environment内部使用的DefaultConversionService不会自动获取PropertyEditor。这可能与:

有关

https://jira.springsource.org/browse/SPR-6564