You need to rename your config.properties
file to application.properties
for Spring Boot to pick it up automatically.
How to autowired profile configuration class on startup?
-
18-07-2023 - |
Pregunta
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.
Solución
Otros consejos
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.