使用带成员的限定符动态触发CDI事件

Ben*_*rby 6 events cdi jboss-weld

我正在尝试在JBoss AS6上的后端服务中使用CDI事件 - 理想情况下是最大程度地重用代码.

我可以从文档中看到我可以通过使用带有成员的限定符来减少必须创建的限定符注释类.

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Type {
    TypeEnum value();
}
Run Code Online (Sandbox Code Playgroud)

我可以观察到这一点

public void onTypeAEvent(@Observes @Type(TypeEnum.TYPEA) String eventMsg) {...}
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.但是,为了进一步减少所需类的数量,我希望有一个EventFirer类,其中抛出的事件的限定符是动态的.没有成员的限定符没有问题:

public class DynamicEventFirer {

    @Inject @Any private Event<String> event;

    public void fireEvent(AnnotationLiteral<?> eventQualifier){
        event.select(eventQualifier).fire("FIRED"); 
    }
}
Run Code Online (Sandbox Code Playgroud)

然后叫做喜欢

dynamicEventFirer.fireEvent(new AnnotationLiteral<Type>() {});
Run Code Online (Sandbox Code Playgroud)

但是,当资格赛成员应该有成员时呢?查看AnnotationLiteral的代码,它肯定是为成员设置的,而class元素注释具有以下示例:

new PayByQualifier() { public PaymentMethod value() { return CHEQUE; } }
Run Code Online (Sandbox Code Playgroud)

这对我来说很有意义 - 你要覆盖注释界面的value()方法.但是,当我自己尝试这个时:

dynamicEventFirer.fireEvent(new AnnotationLiteral<Type>() {
    public TypeEnum value() {
        return TypeEnum.TYPEA;
    }
});
Run Code Online (Sandbox Code Playgroud)

我收到了例外

java.lang.RuntimeException: class uk.co.jam.concept.events.MemberQualifierEventManager$1 does not implement the annotation type with members uk.co.jam.concept.events.Type
    at javax.enterprise.util.AnnotationLiteral.getMembers(AnnotationLiteral.java:69)
    at javax.enterprise.util.AnnotationLiteral.hashCode(AnnotationLiteral.java:281)
    at java.util.HashMap.getEntry(HashMap.java:344)
    at java.util.HashMap.containsKey(HashMap.java:335)
    at java.util.HashSet.contains(HashSet.java:184)
    at org.jboss.weld.util.Beans.mergeInQualifiers(Beans.java:939)
    at org.jboss.weld.bean.builtin.FacadeInjectionPoint.<init>(FacadeInjectionPoint.java:29)
    at org.jboss.weld.event.EventImpl.selectEvent(EventImpl.java:96)
    at org.jboss.weld.event.EventImpl.select(EventImpl.java:80)
    at uk.co.jam.concept.events.DynamicEventFirer.fireEvent(DynamicEventFirer.java:20)
Run Code Online (Sandbox Code Playgroud)

谁能看到我做错了什么?MemberQualifierEventManager是一个ApplicationScoped bean,它调用DynamicEventFirer来触发事件.

谢谢,本

Joh*_*ent 12

根据你的帖子,有一个更简洁的方法:

public class TypeQualifier extends AnnotationLiteral<Type> implements Type{

private TypeEnum type;

public TypeQualifier(TypeEnum t) {
      this.type = t;
}

public TypeEnum value() {
    return type;
}

}
Run Code Online (Sandbox Code Playgroud)

然后像这样开火:

dynamicEventFirer.fireEvent(new TypeQualifier(TypeEnum.TYPEA));
Run Code Online (Sandbox Code Playgroud)