通过CDI.current()。select(Class,Annotation ...)使用可重复的限定词获取确切的bean

时间:2018-11-22 09:41:14

标签: java java-ee dependency-injection annotations

使用CDI和注释@Qualifier

时,我无法获得想要的bean

@Qualifier @interface for Type

@Repeatable(Type.List.class)
@Target({TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Type {

    String value();

    @Target({TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @interface List {
        Type[] value();
    }
}

AnnotationLiteral实施

public class TypeAL extends AnnotationLiteral<Type> implements Type {

    private final String type;

    public TypeAL(String type) {
        this.type = type;
    }

    @Override
    public String value() {
        return type;
    }
}

@Qualifier @interface for Related

@Target({TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Related {

    Class value();
}

AnnotationLiteral实施

public class RelatedAL extends AnnotationLiteral<Related> implements Related {

    private final Class clazz;

    public RelatedAL(Class clazz) {
        this.clazz = clazz;
    }

    @Override
    public Class value() {
        return clazz;
    }
}

当我这样注释时:

@Type(TYPE_ONE)
@Type(TYPE_TWO)
@Related(RelatedClassWhichWillDoLogic.class)
public class LogicToRelatedClass implements BaseLogic {}

当我想获得CDI.current().select(BaseLogic.class, new TypeAL(TYPE_ONE), new RelatedAL(RelatedClassWhichWillDoLogic.class))时,我什么也没做...

那是为什么?

1 个答案:

答案 0 :(得分:0)

您的CDI版本是什么?我认为版本2支持重复的限定词。

https://issues.jboss.org/browse/CDI-471 https://docs.google.com/document/d/1KUaxXIXJ_r-h5UJGIij6I4vrLS7uXkeeeZr2SaRipWQ/edit#

在不同的实现之间选择一个实现。我们可以使用限定符成员来缩小可能的bean列表。注入点必须与Bean上的限定符完全匹配(如果您想要精确的限定符)。您的bean类上有两个Type注释,但在CDI.current()。select方法调用中使用了其中一个。

Instance<BaseLogic> findedBeans = CDI.current().select(BaseLogic.class, new TypeAL("TYPE_ONE"), new TypeAL("TYPE_TWO"), new RelatedAL(RelatedClassWhichWillDoLogic.class));

我在一个Weld Java SE程序中对其进行了测试。您可以从WELD (CDI) + JPA

下载它

在App类的main方法中,添加以下代码行。

UserApplication userApplication = container.instance()
                .select(UserApplication.class)
                .get();
        Instance<BaseLogic> type_one = CDI.current().select(BaseLogic.class, new TypeAL("TYPE_ONE"), new TypeAL("TYPE_TWO"), new RelatedAL(RelatedClassWhichWillDoLogic.class));    

enter image description here