Reputation: 155
I'm Aware that this issue is almost the same as solved in this answer but it's not working for me and my setup is also a bit different.
I want to choose between two implementations of the FooRepository interface. For this, I created the RepositoryManager Configuration. In theory, only one bean should exist at runtime because of the excluding conditions.
In all cases, the "postgres.active"
property is set to false.
@Configuration
public class RepositoryManager {
@Bean(name = "repositoryQualifier")
@ConditionalOnProperty(
value="postgres.active",
havingValue = "true")
public FooRepository managedRepository(PostgresRepository postgresRepository){
return postgresRepository;
}
@Bean(name = "repositoryQualifier")
@ConditionalOnProperty(
value="postgres.active",
havingValue = "false")
public FooRepository managedRepository(RedisRepository redisRepository){
return redisRepository;
}
}
@RestController
public class BarService{
private final FooRepository repository;
@Autowired
public BarService(
@Qualifier("repositoryQualifier") final FooRepository repository,
) {
this.repository = repository;
}
}
When I try to run this example Spring throws this error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying
bean of type 'org.test.FooRepository' available: expected
at least 1 bean which qualifies as autowire candidate. Dependency annotations:
{@org.springframework.beans.factory.annotation.Qualifier(value="repositoryQualifier")
If I comment one of the Beans and remove the condition from the not commented one it finds the bean so it shouldn't be an issue with locating the package or the bean. I'm desperate, I'm already struggling with this for 6h now
Upvotes: 1
Views: 3133
Reputation: 1490
PostgresRepository
and RedisRepository
are subclasses of or implement FooRepository
, right? please try out if it works without specifying an explicit bean name in the @Bean
annotations - also it might also be an option to use @ConditionalOnExpression
instead but ofc your way should basically also work just fine, e.g. as follows:
@Configuration
public class RepositoryManager {
@Bean
@ConditionalOnExpression("${postgres.active}")
public FooRepository managedRepository(PostgresRepository postgresRepository){
return postgresRepository;
}
@Bean
@ConditionalOnExpression("!${postgres.active}")
public FooRepository managedRepository(RedisRepository redisRepository){
return redisRepository;
}
}
@RestController
public class BarService{
private final FooRepository repository;
@Autowired
public BarService(final FooRepository repository,
) {
this.repository = repository;
}
}
Upvotes: 2
Reputation: 66
Maybe try using the Bean name:
@Autowired
public BarService(@Qualifier("repositoryQualifier") FooRepository managedRepository) {
repository = managedRepository;
}
Also, why are you using the same Qualifier name for both methods ? Try also to change the name of the second method.
Upvotes: 0