我正在尝试在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的代码,它肯定是为成员设置的,并且类元素注释包含以下示例:
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来触发事件。
谢谢,
有一种基于您的帖子的更简洁的方法:
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));