2011-08-03 26 views
4

我試圖在JBoss AS6的後端服務中使用CDI事件 - 理想情況下最大程度地重複使用代碼。動態激發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來觸發事件。

感謝, 本

回答

9

有做一個稍微乾淨的方式是根據您的文章:

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)); 
+0

謝謝約翰,使用這個作爲,如果我創建一個單獨的類,我不妨使用它來使調用代碼儘可能簡短! –

0

你需要聲明的是擴展AnnotationLiteral並實現一個抽象TypeQualifier鍵入

abstract 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; 
} 
}); 
+0

非常感謝扎克,這會工作。沒有意識到我需要一個explcit類。 –

相關問題