7

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) {...}

ここまでは順調ですね。ただし、必要なクラスの数をさらに削減するために、スローされるイベントの修飾子が動的である 1 つの 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 は、DynamicEventFirer を呼び出してイベントを発生させる ApplicationScoped Bean です。

ありがとう、ベン

4

2 に答える 2

0

AnnotationLiteral を拡張して Type を実装する抽象 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;
}
});
于 2011-08-03T19:09:31.660 に答える