我正在尝试在JBoss AS6上的后端服务中使用CDI事件 - 理想情况下是最大程度地重用代码。
我可以从文档中看到,我可以通过使用带有成员的限定符来减少必须创建的限定符注释类。
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Type {
TypeEnum value();
}
我可以用
来观察public void onTypeAEvent(@Observes @Type(TypeEnum.TYPEA) String eventMsg) {...}
到目前为止,这么好。但是,为了进一步减少所需类的数量,我希望有一个EventFirer类,其中抛出的事件的限定符是动态的。没有成员的限定符没有问题:
public class DynamicEventFirer {
@Inject @Any private Event<String> event;
public void fireEvent(AnnotationLiteral<?> eventQualifier){
event.select(eventQualifier).fire("FIRED");
}
}
然后调用
dynamicEventFirer.fireEvent(new AnnotationLiteral<Type>() {});
但是限定词应该有成员呢?查看AnnotationLiteral的代码,它肯定是为成员设置的,而class元素注释有例子:
new PayByQualifier() { public PaymentMethod value() { return CHEQUE; } }
这对我有意义 - 你要覆盖注释界面的value()方法。但是,当我自己尝试这个时:
dynamicEventFirer.fireEvent(new AnnotationLiteral<Type>() {
public TypeEnum value() {
return TypeEnum.TYPEA;
}
});
我收到了例外
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)
谁能看到我做错了什么? MemberQualifierEventManager是一个ApplicationScoped bean,它调用DynamicEventFirer来触发事件。
谢谢, 本
答案 0 :(得分:10)
根据您的帖子,有一种更简洁的方法:
public class TypeQualifier extends AnnotationLiteral<Type> implements Type{
private TypeEnum type;
public TypeQualifier(TypeEnum t) {
this.type = t;
}
public TypeEnum value() {
return type;
}
}
然后就这样开火:
dynamicEventFirer.fireEvent(new TypeQualifier(TypeEnum.TYPEA));
答案 1 :(得分:0)
您需要声明一个扩展AnnotationLiteral并实现Type
的抽象TypeQualifierabstract class TypeQualifier extends AnnotationLiteral<Type> implements Type{}
并像这样使用
dynamicEventFirer.fireEvent(new TypeQualifier() {
public TypeEnum value() {
return TypeEnum.TYPEA;
}
});
以及稍后如果要使用TypeEnum.TYPEB
触发事件dynamicEventFirer.fireEvent(new TypeQualifier() {
public TypeEnum value() {
return TypeEnum.TYPEB;
}
});