【问题标题】:Overriding Spring @PropertySource by @Import@Import 覆盖 Spring @PropertySource
【发布时间】:2013-03-12 17:02:25
【问题描述】:

我在 DefaultConfig 类中有一个属性 test=default,我正在使用 @PropertySource 注释使它们可用。

@Configuration
@PropertySource("classpath:default.properties")
public class DefaultConfig {}

然后我希望能够覆盖到 test=override,它位于类 OverrideConfig 的不同属性文件中,所以我再次使用 @PropertySource。

@Configuration
@Import(DefaultConfig.class)
@PropertySource("classpath:override.properties")
public class OverrideConfig {}

我配置了一个测试来证明它有效。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={OverrideConfig.class})
public class TestPropertyOverride {

    @Autowired
    private Environment env;

    @Test
    public void propertyIsOverridden() {
        assertEquals("override", env.getProperty("test"));
    }

}

当然不是。

org.junit.ComparisonFailure: expected:<[override]> but was:<[default]>

最大化调试,我可以看到发生了什么:

StandardEnvironment:107 - Adding [class path resource [default.properties]] PropertySource with lowest search precedence
StandardEnvironment:107 - Adding [class path resource [override.properties]] PropertySource with lowest search precedence

似乎倒退了。我是否犯了一个简单的错误或误解了这一点,或者您是否希望@Import-ed 配置类中的@PropertySource 定义的属性被@Import-ing 类中的@PropertySource 中定义的属性覆盖?

【问题讨论】:

  • 可能发生的情况是,您的OverrideConfig 类上的注释首先被评估,因此test=override,然后DefaultConfig 类被导入,它的注释被评估,test 被覆盖到default

标签: spring properties


【解决方案1】:

这是Helder Sousa 的解决方案,写为a comment of the JIRA issue 由OP 创建:

[T]spring xml 中可用的行为(一个 xml 导入另一个 xml)可以使用嵌套配置实现:

@Configuration
@PropertySource("classpath:default.properties")
public class DefaultConfig {}
@Configuration
@PropertySource("classpath:override.properties")
public class OverrideConfig {

    @Configuration
    @Import(DefaultConfig.class)
    static class InnerConfiguration {}

}

通过此设置,属性将以正确的顺序收集。

【讨论】:

    【解决方案2】:

    今天 Spring 4 你可以使用这个:

    @TestPropertySource(value="classpath:/config/test.properties")
    

    这可用于使用并最终覆盖 junit 测试的属性:

    @RunWith(SpringJUnit4ClassRunner.class)
    @TestPropertySource(value="classpath:/config/test.properties")
    

    【讨论】:

      【解决方案3】:

      我遇到了类似的问题,并且成功地在我的自定义配置中声明了默认属性:

      @Configuration
      @Import(DefaultConfig.class)
      @PropertySource({"classpath:default.properties", "classpath:override.properties"})
      public class OverrideConfig {}
      

      【讨论】:

        【解决方案4】:

        您可以像这样强制执行属性的加载顺序:

        @Configuration
        @PropertySource(value={"classpath:default.properties","classpath:override.properties"})
        public class OverrideConfig {
        ...
        }
        

        【讨论】:

          【解决方案5】:

          我目前在 Spring 3.1 中遇到类似情况,但我使用不同的方法来覆盖属性,因为 @PropertySource 不支持可选属性文件:

          @Configuration
          @PropertySource("classpath:default.properties")
          public class BaseConfig {
          
            @Inject
            private ApplicationContext context;
          
            @PostConstruct
            public void init() throws IOException {
              Resource runtimeProps = context.getResource("classpath:override.properties");
              if (runtimeProps.exists()) {
                MutablePropertySources sources = ((ConfigurableApplicationContext) context).getEnvironment().getPropertySources();
                sources.addFirst(new ResourcePropertySource(runtimeProps));
              }
            }
          ...
          

          似乎@Import 不会导致任何特定的@Configuration 实例化顺序,除了正常的bean 依赖关系所规定的顺序。强制执行此类命令的一种方法是将基本 @Configuration 实例本身作为依赖项注入。你可以试试:

          @Configuration
          @Import(DefaultConfig.class)
          @PropertySource("classpath:override.properties")
          public class OverrideConfig {
          
            @Inject
            private DefaultConfig defaultConfig;
          
            ...
          }
          

          这有帮助吗? 也许新的ContextHierarchy 注释在这里也可以提供帮助,但到目前为止我还没有尝试过这个。

          【讨论】:

          • 恐怕没用。据我所知,这种行为就是这样,除非 Spring 人员同意改变它。案例提出。
          • 阿门。尽管我讨厌 XML 接线,但我确实想念<context:property-placeholder ignore-resource-not-found="true" location="classpath:base.config,file:override.config" />
          猜你喜欢
          • 1970-01-01
          • 2016-08-05
          • 2012-12-22
          • 1970-01-01
          • 1970-01-01
          • 2018-05-02
          • 2014-10-26
          • 1970-01-01
          • 2015-07-28
          相关资源
          最近更新 更多