LppEdd :
I created a custom Spring @Qualifier
annotation:
@Target({
ElementType.FIELD,
ElementType.METHOD,
ElementType.PARAMETER,
ElementType.TYPE,
ElementType.ANNOTATION_TYPE
})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Database {
String value() default "";
}
I then applyed this annotation to the various implementing Beans:
@Repository
@Database("mysql")
class MySqlActionRepository implements ActionRepository {}
@Repository
@Database("oracle")
class OracleActionRepository implements ActionRepository {}
@Repository
@Database("sqlserver")
class SqlServerActionRepository implements ActionRepository {}
Now, being that at runtime, only one of these Beans has to be available for injection, I created a @Primary
Bean method.
@Bean
@Primary
ActionRepository actionRepository(
final ApplicationContext applicationContext,
final Configuration configuration) {
final var database = configuration.getString("...");
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(
applicationContext,
ActionRepository.class,
database
);
}
However this solution does not work with my custom annotation. It works only when using the standard @Qualifier
one.
Any idea how I could solve this issue?
Ken Chan :
Seem that from here , BeanFactoryAnnotationUtils
does not support your case . But we can combine ApplicationContext
's getBeansOfType()
and findAnnotationOnBean()
to achieve the same purpose :
@Bean
@Primary
ActionRepository actionRepository(final ApplicationContext applicationContext,
final Configuration configuration) {
final var database = configuration.getString("...");
Map<String, ActionRepository> beanMap = context.getBeansOfType(ActionRepository.class);
for (Map.Entry<String, ActionRepository> entry : beanMap.entrySet()) {
Database db = context.findAnnotationOnBean(entry.getKey(), Database.class);
if (db != null && db.value().equals(database)) {
return entry.getValue();
}
}
throw new RuntimeException("Cannot find the bean...");
}