2013-03-22 13 views
11

Mam właściwość test=default w klasie DefaultConfig i udostępniam je przy użyciu adnotacji @PropertySource.Przesłanianie Spring @PropertySource przez @Import

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

Następnie chcę, aby móc zastąpić do test=override, który znajduje się w innym pliku właściwości w klasie OverrideConfig, więc ponownie użyć @PropertySource.

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

Konfiguruję test, aby udowodnić, że działa.

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

    @Autowired 
    private Environment env; 

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

} 

Oczywiście, że nie.

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

maxing debugowania, widzę, co się dzieje:

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 

Wydaje tyłu. Czy popełniam prosty błąd lub mylę się z tym, czy spodziewalibyście się, że właściwości zdefiniowane przez @PropertySource w klasie konfiguracji @ Import-ed zostaną nadpisane przez właściwości zdefiniowane w am @PropertySource w klasie @ Importing?

+2

Co się dzieje jest to, że prawdopodobnie adnotacje na swojej 'OverrideConfig' klasy są oceniane przede więc' test = override', wówczas 'klasa DefaultConfig' jest importowany i jego adnotacje są oceniane i' test' zastąpieniem do 'default' –

+0

Wywołany problem https://jira.springsource.org/browse/SPR-10409 – Brabster

Odpowiedz

1

Jestem obecnie zmaga się z podobnym przypadku wiosną 3.1 ale używam innego podejścia do nadpisania właściwości, ponieważ @PropertySource nie obsługuje opcjonalne pliki własności:

@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)); 
    } 
    } 
... 

Wydaje się, że nie robi @Import powoduje dowolną kolejność wykonywania dowolnej instancji, poza porządkiem dyktowanym przez normalne zależności od komponentów bean. Sposobem na wymuszenie takiego zamówienia jest wstrzyknięcie samej instancji podstawowej jako zależności. Czy możesz spróbować:

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

    @Inject 
    private DefaultConfig defaultConfig; 

    ... 
} 

Czy to pomoże? A może nowa adnotacja ContextHierarchy może być tu pomocna, ale nie wypróbowałem tego do tej pory.

+0

Obawiam się, że to nie pomoże. O ile mogę powiedzieć, to zachowanie jest po prostu takie, jak jest, chyba że ludzie wiosenni zgodzą się go zmienić. Sprawa podniesiona. – Brabster

+1

Amen. Tak jak nie cierpię okablowania XML, brakuje mi '' –

1

Można wymusić kolejność ładowania właściwościach tak:

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

miałem podobny problem i udało mu się po prostu deklarując również właściwość domyślną w moim konfiguracji niestandardowej:

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

Today ze Spring 4 możesz użyć:

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

I to może być użyte t O użyciu i ewentualnie zastąpić właściwości testu junit:

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

Oto rozwiązanie według Helder Sousa napisany w a comment of the JIRA issue utworzonej przez OP:

[k] zachowania dostępnych w sprężyny XML (jeden XML importowania inny XML) jest osiągalne z użyciem zagnieżdżone konfiguracje:

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

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

} 

Przy tej konfiguracji właściwości zostaną zebrane we właściwej kolejności.