Spring - getting bean at runtime with custom qualifier

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...");
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=160549&siteId=1