Reputation: 66
I'm trying to implement a service, which will use two different repositories based on env
variable.
Based on this article: https://reflectoring.io/dont-use-spring-profile-annotation/
I want to use configuration with @ConditionalOnProperty
annotation to load appropriate implementation on startup.
I did everything exactly like in the article, but spring throws an exception saying that the bean is not defined:
Description:
Parameter 0 of method myService in com.adam.MyServiceConfiguration required a bean of type 'com.adam.MyRepository' that could not be found.
Action:
Consider defining a bean of type 'com.adam.MyRepository' in your configuration.
Process finished with exit code 0
Here is the configuration of service:
@Configuration
class MyServiceConfiguration {
@Bean
fun mySerivce(myRepository: MyRepository) = MyService(myRepository)
}
And here is the configuration of repository beans:
@Configuration
class DataSourceConfiguration {
@Bean
@ConditionalOnProperty(
prefix = "datasource",
name = ["mock"],
havingValue = "false",
matchIfMissing = true
)
fun myRepository(httpClient: HttpClient): MyRepository =
HttpRepository(httpClient)
@Bean
@ConditionalOnProperty(
prefix = "datasource",
name = ["mock"],
havingValue = "true"
)
fun myRepository(): MyRepository = InMemoryRepository()
}
Can anybody see what am I doing wrong? I'm struggling with it for hours.
I tried using @DependsOn but then the error was that there is no bean defined of that name.
I also enabled logging and if I'm reading this right the bean should be resolved properly:
My#repository:
Did not match:
- @ConditionalOnProperty (datasource.mock=false) found different value in property 'mock' (OnPropertyCondition)
Matched:
- @ConditionalOnProperty (datasource.mock=true) matched (OnPropertyCondition)
Upvotes: 2
Views: 6928
Reputation: 116061
You have two @Bean
methods named myRepository
on one @Configuration
class. This means that there are two different methods both defining a bean named myRepository
. This confuses Spring Framework's condition evaluation as described in this issue. The confusion means that the conditions on both myRepository()
methods are evaluated when defining a single myRepository
bean. Your two conditions are mutually exclusive so no bean is defined.
You can fix the problem by ensuring that your two @Bean
methods have distinct names. For example you could name them httpRepository
and inMemoryRepository
.
Upvotes: 2