简体   繁体   English

Spring - 在运行时使用自定义限定符获取 bean

[英]Spring - getting bean at runtime with custom qualifier

I created a custom Spring @Qualifier annotation:我创建了一个自定义 Spring @Qualifier注释:

@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:然后我将此注释应用于各种实现 Bean:

@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 Bean 方法。

@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.它仅在使用标准@Qualifier

Any idea how I could solve this issue?知道我如何解决这个问题吗?

Seem that from here , BeanFactoryAnnotationUtils does not support your case .这里看来, BeanFactoryAnnotationUtils不支持您的情况。 But we can combine ApplicationContext 's getBeansOfType() and findAnnotationOnBean() to achieve the same purpose :但是我们可以结合ApplicationContextgetBeansOfType()findAnnotationOnBean()来达到同样的目的:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM