2013-03-22 96 views
11

我在DefaultConfig類中有一個屬性test=default,我使用@PropertySource註釋使它們可用。通過@Import覆蓋Spring @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中定義的屬性覆蓋?

+2

可能發生的情況是,您的OverrideConfig類的註釋首先被評估,然後'test = override',那麼'DefaultConfig'類被導入,其註釋被評估並且'test'被覆蓋'default' – 2013-03-22 20:36:18

+0

引發問題https://jira.springsource.org/browse/SPR-10409 – Brabster 2013-03-23 08:42:08

回答

1

我目前有類似的情況下掙扎在春季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不除了正常的bean依賴關係規定的順序外,還可以導致任何特定順序的實例化。強制執行此命令的一種方法是將基礎@Configuration實例本身注入爲依賴項。您可以嘗試:

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

    @Inject 
    private DefaultConfig defaultConfig; 

    ... 
} 

這對您有幫助嗎? 也許新的ContextHierarchy註釋也可以在這裏幫助,但我到目前爲止沒有嘗試這個。

+0

恐怕沒有幫助。據我所知,這種行爲就是這樣,除非春天人們同意改變它。案例提出。 – Brabster 2013-04-25 17:21:04

+1

阿門。儘管我討厭XML接線,但我確實懷疑' 2013-09-26 03:24:04

1

你可以強制你的屬性的加載順序是這樣的:

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

我也有類似的問題,併成功也只是宣稱默認屬性在我的自定義配置:

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

今天與春季4你可以使用這個:

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

而且這可以使用t o使用並最終覆蓋爲JUnit測試屬性:

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

這裏是由Helder Sousa的溶液中,寫入由OP創建a comment of the JIRA issue

[T],以彈簧的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 {} 

} 

使用此設置,屬性將以正確的順序收集。