これはかなり単純明快な質問のようですが、どこにも答えが見つからないようです。
Springでは、次のように@EventListenerアノテーションを使用してイベントのリスナーを作成できます。
@Component
public class MyListener {
@EventListener
public void handleEvent(ContextRefreshedEvent event) {
...
}
}
ただし、複数のイベントをリッスンし、発生するイベントに基づいて異なる動作をするために同じメソッドが必要な場合はどうなりますか?
直感的に、私はこれに似たものを考えています:
@Component
public class MyListener {
@EventListener
public void handleEvents(ContextRefreshedEvent event, ContextStopped event) {
String event;
if(event instanceof ContextRefreshedEvent)
event = "Refreshed";
if(event instanceof ContextStoppedEvent)
event = "Stopped";
}
}
EventListenerアノテーションが複数のイベントをリッスンする正しい方法は何ですか?同じメソッドが実際に発生するイベントに基づいてどのように区別できるのですか?
どうもありがとう。
複数のイベントをリッスンするイベントリスナーを作成することは、名目上簡単です。
@EventListener({EventA.class, EventB.class})
public doSomething() {
...
}
ただし、明らかにこのアプローチでは、基になるイベントにアクセスできません。 EventListener
のjavadocに基づいて、あなたが提案していることを行うことができないようです
アノテーション付きメソッドが単一のイベントタイプをサポートする場合、メソッドは、リッスンするイベントタイプを反映する単一のパラメーターを宣言する場合があります。アノテーション付きメソッドが複数のイベントタイプをサポートしている場合、このアノテーションは、classes属性を使用して、サポートされている1つ以上のイベントタイプを参照する場合があります。詳細は、classes()javadocを参照してください。
...
(
classes
)属性が単一の値で指定されている場合、注釈付きメソッドはオプションで単一のパラメーターを受け入れることができます。ただし、この属性が複数の値で指定されている場合、注釈付きメソッドはパラメーターを宣言してはなりません。
したがって、複数のイベントを消費し、それらのイベントの本体に基づいて異なるアクションを実行するメカニズムはないようです。ただし、これは必要ではないことをお勧めします。イベント固有の@EventListener
メソッドを常に登録し、共有メソッドを呼び出して一般的な機能を実行させることもできます。
Spring 4.2以降では、メソッド宣言でサブクラスを使用して、このサブクラスを拡張するすべてのイベントを処理できます。
@EventListener
public void handleEvent(ApplicationEvent event) {
// listen all descendants of the ApplicationEvent
}
また、アノテーションの属性を使用して、イベントのリストを絞り込むこともできます。
@EventListener({ContextRefreshedEvent.class, ApplicationReadyEvent.class})
public void handleEvent(Object event) {
// listen only ContextRefreshedEvent and ApplicationReadyEvent
}
このようなことをしてみませんか。
SpringFramework 4.2
から、ApplicationEvent
を拡張せずにイベントを公開できます。
あなたが答えたとき、あなたは主にカスタムイベントを聞きたいと思っています。このようなことができます。
BaseEvent
という基本クラスを作成します。
public class BaseEvent {
private String type;
public BaseEvent() {}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
カスタムEvent
を公開するときはいつでも、それを基本クラスと見なしてください。
次に、Example1Event
およびExample2Event
という2つのカスタムイベントを作成します。
Example1Event
クラス
public class Example1Event extends BaseEvent {
private String message;
public Example1Event() {}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Example2Event
クラス
public class Example2Event extends BaseEvent {
private String message;
public Example2Event() {}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
EventListener
は次のようになります。
public class EventReceiver {
public EventReceiver() {}
@EventListener
public void receiveEvent(BaseEvent event) {
String eventType = event.getType();
if (eventType.equals("example1")) {
Example1Event example1Event = (Example1Event) event;
System.out.println(example1Event.getMessage());
} else if (eventType.equals("example2")) {
Example2Event example2Event = (Example2Event) event;
System.out.println(example2Event.getMessage());
}
}
}
これはあなたがしたいことのために働くでしょう。
イベントごとに複数のEventListenerを持つことができます。