代码之家  ›  专栏  ›  技术社区  ›  LppEdd

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

  •  2
  • LppEdd  · 技术社区  · 7 年前

    我创造了一个定制的春天 @Qualifier 注释:

    @Target({
            ElementType.FIELD,
            ElementType.METHOD,
            ElementType.PARAMETER, 
            ElementType.TYPE,
            ElementType.ANNOTATION_TYPE
    })
    @Retention(RetentionPolicy.RUNTIME)
    @Qualifier
    public @interface Database {
        String value() default "";
    }
    

    然后,我将此注释应用于各种实现bean:

    @Repository
    @Database("mysql")
    class MySqlActionRepository implements ActionRepository {}
    
    @Repository
    @Database("oracle")
    class OracleActionRepository implements ActionRepository {}
    
    @Repository
    @Database("sqlserver")
    class SqlServerActionRepository implements ActionRepository {}
    

    现在,由于在运行时,这些bean中只有一个必须可用于注入,所以我创建了一个 @Primary 豆法。

    @Bean
    @Primary
    ActionRepository actionRepository(
            final ApplicationContext applicationContext,
            final Configuration configuration) {
        final var database = configuration.getString("...");
        return BeanFactoryAnnotationUtils.qualifiedBeanOfType(
                applicationContext,
                ActionRepository.class,
                database
        );
    }
    

    但是这个解决方案 使用我的自定义批注。只有在使用标准时才有效 限定词 一个。

    我知道如何解决这个问题吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Ken Chan    7 年前

    似乎来自 here , BeanFactoryAnnotationUtils 不支持您的案例。但我们可以结合 ApplicationContext getBeansOfType() 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...");
    }