通过@Import覆盖Spring @PropertySource

vfwfrxfs  于 2023-05-16  发布在  Spring
关注(0)|答案(5)|浏览(242)

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

ax6ht2ek

ax6ht2ek1#

以下是Helder Sousa的解决方案,作为OP创建的JIRA问题的评论:
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 {}

}

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

js5cn81o

js5cn81o2#

在Spring 4中,你可以使用:

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

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

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

11dmarpk3#

我目前在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注解在这里也会有帮助,但到目前为止我还没有尝试过。

umuewwlo

umuewwlo4#

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

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

vcirk6k65#

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

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

相关问题