Jak skonfigurować Spring, aby częściowo i opcjonalnie przesłonił właściwości?

Chciałbym mieć konfigurację właściwości, która w pewnych środowiskach może zastąpić określone właściwości. Na przykład nasze domyślne właściwości JDBC dla dev to:

db.driverClassName = com.mysql.jdbc.Driverdb.url = jdbc: mysql: // localhost: 3306 / ourdbdb.username = rootdb.password =

Problem polega na tym, że niektórzy z naszych deweloperów chcieliby mieć inną nazwę użytkownika / hasło w db, a nawet w db nie obsługiwanym lokalnie. To samo dotyczy naszej konfiguracji rabbitMQ, która obecnie używa podobnego hosta lokalnego, konfiguracji gościa / gościa. Możliwość zastąpienia właściwości niektórych elementów tej konfiguracji dla poszczególnych programistów pozwoliłaby nam przenieść większość wymagań dotyczących infrastruktury / instalacji w celu zbudowania oprogramowania z lokalnej maszyny i na dedykowane serwery.

Skonstruowałem prosty projekt, aby objąć głowę wymaganą konfiguracją, aby osiągnąć to, czego chcę, i to jest mój pierwszy krok w świat konfigurowania właściwości wiosennych, ponieważ do tej pory ładowanie i zarządzanie nieruchomościami odbywało się z pewnym niestandardowym kod. Oto moja konfiguracja:

class Main_PropertyTest {
    public static void main(String[] args) {
        String environment = System.getenv("APPLICATION_ENVIRONMENT"); // Environment, for example: "dev"
        String subEnvironment = System.getenv("APPLICATION_SUB_ENVIRONMENT"); // Developer name, for example: "joe.bloggs"
        System.setProperty("spring.profiles.active", environment);
        System.setProperty("spring.profiles.sub", subEnvironment);

        try(AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PropertyTestConfiguration.class)) {
            Main_PropertyTest main = context.getBean(Main_PropertyTest.class);
            main.printProperty();
        }
    }

    private final String property;

    public Main_PropertyTest(String property) {
        this.property = property;
    }

    public void printProperty() {
        System.out.println("And the property is: '" + property + "'.");
    }
}

I moja konfiguracja:

@Configuration
public class PropertyTestConfiguration {
    @Bean
    public static PropertySourcesPlaceholderConfigurer primaryPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        propertySourcesPlaceholderConfigurer.setLocation(new ClassPathResource(System.getProperty("spring.profiles.active") + ".main.properties"));
        return propertySourcesPlaceholderConfigurer;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer secondaryPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        propertySourcesPlaceholderConfigurer.setLocation(new ClassPathResource(System.getProperty("spring.profiles.sub") + ".main.properties"));
        propertySourcesPlaceholderConfigurer.setIgnoreResourceNotFound(true);
        propertySourcesPlaceholderConfigurer.setIgnoreResourceNotFound(true);
        propertySourcesPlaceholderConfigurer.setOrder(-1);
        return propertySourcesPlaceholderConfigurer;
    }

    @Bean
    public Main_PropertyTest main_PropertyTest(@Value("${main.property}") String property) {
        Main_PropertyTest main_PropertyTest = new Main_PropertyTest(property);
        return main_PropertyTest;
    }
}

I dla kompletności moje dev.main.properties i test.main.properties:

main.property=dev

main.property=test

Główny problem polega na tym, że otrzymuję wyjątek niezgodny z prawem. O ile wiem, to, co napisałem, powinno być odpowiednikiem tej metody w javaconfig:http://taidevcouk.wordpress.com/2013/07/04/overriding-a-pakiet-spring-application-properties-file-via-an-external-file/ Niestety pojawia się następujący błąd: java.lang.IllegalArgumentException: Nie można rozwiązać symbolu zastępczego „main.property” w wartości ciągu „$ {main.property}”. Zauważ, że muszę również zająć się sprawą, w której nie ma podśrodowiska, i to jest przypadek, w którym zacząłem (chociaż otrzymuję ten sam błąd, nawet jeśli oba pliki istnieją). Jeśli usuwam komponent bean, który ustawia drugi właściwość propertysourcesplaceholderfigurer, to wszystko działa poprawnie (przez co rozumiem, że dev.main.properties jest ładowany i „A właściwość to:„ dev '. ”Jest drukowana).

Dodatkowym problemem jest to, że kod nie wygląda wspaniale, a każda warstwa systemu będzie potrzebować dwóch ustawień PSPC, aby uzyskać dostęp do tych właściwości. Ponadto wymaga dużo ręcznych wywołań do System.getProperty (), ponieważ nie mogłem przekazać $ {spring.profiles.active} do PSPC.setLocation ();

Uwaga: Wypróbowałem @PropertySources ({primaryproperties, secondaryProperties}), ale to się nie powiedzie, ponieważ secondaryProperties nie istnieje. Próbowałem także środowiska @Autowired Environment; i uzyskiwanie z tego właściwości, ale wtórny PSPC powoduje, że środowisko nie jest automatycznie traktowane ...

Więc po tym długim wyjaśnieniu moje pytania to:

Czy to właściwy sposób rozwiązania tego problemu?Jeśli tak, co jest nie tak z moją konfiguracją?Jak mogę uprościć konfigurację (jeśli w ogóle)?Czy dostępny jest alternatywny mechanizm, który rozwiąże mój problem?

Dziękuję za Twój czas! :)

questionAnswers(2)

yourAnswerToTheQuestion