13

我在类 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 中定义的属性覆盖?

4

5 回答 5

7

这是Helder Sousa的解决方案,作为对 OP 创建的 JIRA 问题的评论:

[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 {}

}

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

于 2015-08-28T20:54:00.263 回答
2

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

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

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

@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(value="classpath:/config/test.properties")
于 2015-03-29T16:13:34.203 回答
1

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

@Configuration
@PropertySource(value={"classpath:default.properties","classpath:override.properties"})
public class OverrideConfig {
...
}
于 2013-06-08T05:47:57.753 回答
1

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

@Configuration
@Import(DefaultConfig.class)
@PropertySource({"classpath:default.properties", "classpath:override.properties"})
public class OverrideConfig {}
于 2014-03-21T10:48:58.120 回答
1

我目前在 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));
    }
  }
...

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

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

  @Inject
  private DefaultConfig defaultConfig;

  ...
}

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

于 2013-04-25T11:00:26.423 回答