¿Cómo configuro Spring para anular parcial y opcionalmente las propiedades?

Me gustaría tener una configuración de propiedades que pueda, en ciertos entornos, anular propiedades específicas. Por ejemplo, nuestras propiedades JDBC predeterminadas para dev son:

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

El problema es que a algunos de nuestros desarrolladores les gustaría tener un nombre de usuario / contraseña diferente en la base de datos, o posiblemente incluso una base de datos no alojada localmente. Lo mismo es cierto para nuestra configuración de rabbitMQ, que actualmente utiliza una configuración de invitado / invitado de localhost similar. Ser capaz de anular las propiedades de ciertos elementos de esta configuración en función de cada desarrollador nos permitiría trasladar gran parte de los requisitos de infraestructura / instalación para compilar el software desde la máquina local a servidores dedicados.

He configurado un proyecto simple para envolver mi cabeza en torno a la configuración requerida para lograr lo que quiero, y esta es mi primera incursión en el mundo de la configuración de propiedades de Spring, ya que hasta ahora, la administración y carga de propiedades se realiza con cierta personalización. código. He aquí mi arreglo:

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 + "'.");
    }
}

Y mi configuración:

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

Y para completar, mis dev.main.properties y test.main.properties:

main.property=dev

main.property=test

El principal problema es que obtengo una excepción de argumento ilegal. Por lo que puedo decir, lo que he escrito debe ser el equivalente javaconfig de este método:http://taidevcouk.wordpress.com/2013/07/04/overriding-a-packaged-spring-application-properties-file-via-an-external-file/ Desafortunadamente, obtengo el siguiente error: java.lang.IllegalArgumentException: No se pudo resolver el marcador de posición 'main.property' en el valor de cadena "$ {main.property}". Tenga en cuenta que también necesito encargarme del caso en el que no exista un entorno secundario, y este es el caso con el que comencé (aunque me sale el mismo error aunque existan ambos archivos). Si elimino el bean que configura el segundo propertysourcesplaceholderconfigurer, entonces todo funciona bien (me refiero a que dev.main.properties se carga y se imprime "Y la propiedad es: 'dev'.").

Un problema secundario es que el código no se ve bien, y cada capa del sistema necesitará dos configuraciones de PSPC para que puedan acceder a estas propiedades. Además, requiere un montón de llamadas manuales a System.getProperty (), ya que no pude pasar $ {spring.profiles.active} a PSPC.setLocation ();

Nota: He intentado @PropertySources ({primaryproperties, secondaryProperties}), pero esto falla porque el valor de InitialProperties no existe. También he probado el entorno @Autowired Environment; y obtener las propiedades a partir de eso, pero la PSPC secundaria hace que el entorno no sea autowired ...

Así que siguiendo esta larga explicación, mis preguntas son:

¿Es esta la manera correcta de resolver este problema?Si es así, ¿qué hay de malo con mi configuración?¿Cómo puedo simplificar la configuración (si la hay)?¿Hay algún mecanismo alternativo disponible que solucione mi problema?

¡Gracias por tu tiempo! :)

Respuestas a la pregunta(2)

Su respuesta a la pregunta