Question

I'd like to create different database profile classes, each for a purpose of development, production and testing.

I tried the following with the help of http://spring.io/blog/2011/02/14/spring-3-1-m1-introducing-profile/, but it won't wire correctly. Why?

 interface DataConfig {
        DataSource dataSource();
    }

    @Configuration
    @Profile("dev")
    public class StandaloneDataConfig implements DataConfig {
        @Bean
        @Override
        public dataSource dataSource() {
            //return the ds
        }
    }

    @Configuration
    @Profile("prod")
    public class JndiDataConfig implements DataConfig { ... }

    @Configuration
    @PropertySource({"classpath:config.properties"})
    class AppConfig {
        @Autowired
        private DataConfig cfg;

    }

@Configuration
@ComponentScan
@Import(AppConfig.class)
@EnableTransactionManagement
public class SpringBootConfig extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }
}

config.properties:

spring.profiles.active=dev

Result: Exception on startup

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private DataConfig dataConfig; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [DataConfig] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
    ... 34 common frames omitted

Spring 4.0.3.RELEASE

My setup though seem to work in general: if I remove the @Profile annotation on one of the databases, everything wires up correctly.

Was it helpful?

Solution

You need to rename your config.properties file to application.properties for Spring Boot to pick it up automatically.

OTHER TIPS

I haven't tested your configuration, but my best guess (following some investigation I've done for this post) is that @PropertySources are not available for a @Conditional annotated @Configuration class when autowiring occurs.

According to the source code, @Profile is a @Conditional flavor of annotation with a Condition implementation. For @PropertySource to be available when they are needed I think you would need your own custom @Conditional implementation just like in the SO post I mentioned above, where you define not a Condition but a ConfigurationCondition making sure to be used at ConfigurationPhase.REGISTER_BEAN phase.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top