【问题标题】:Spring @PropertySource and Environment Type ConversionsSpring @PropertySource 和环境类型转换
【发布时间】:2013-11-28 15:23:46
【问题描述】:

我有一个现有的基于 xml 的 spring 配置,使用 PropertyPlaceholderConfigurer,如下所示:

  <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' 属性的设置器接受 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 为我执行此操作时,我为什么需要这样做?

【问题讨论】:

    标签: spring type-conversion spring-annotations


    【解决方案1】:

    我已经解决了这个问题。

    我已经意识到从资源包中获取属性和在 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

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,结果证明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") 注释。

      【讨论】:

      • 谢谢 n1ckolas,我以前见过这种方式 - 正如你所说的它相当于 xml。但是,我认为这正是 @PropertySource 注释应该避免的?
      猜你喜欢
      • 1970-01-01
      • 2017-09-24
      • 1970-01-01
      • 2020-06-09
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2018-08-03
      • 1970-01-01
      相关资源
      最近更新 更多