EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监听和发布订阅模式,EventBus是一个非常优雅和简单解决方案,我们不用创建复杂的类和接口层次结构。
Guide
For Listeners
To listen for a specific flavor of event (say, a CustomerChangeEvent
)...
-
...in traditional Java events: implement an interface defined with the event -- such as
CustomerChangeEventListener
. -
...with
EventBus
: create a method that acceptsCustomerChangeEvent
as its sole argument, and mark it with the@Subscribe
annotation.
To register your listener methods with the event producers...
-
...in traditional Java events: pass your object to each producer's
registerCustomerChangeEventListener
method. These methods are rarely defined in common interfaces, so in addition to knowing every possible producer, you must also know its type. -
...with
EventBus
: pass your object to theEventBus.register(Object)
method on anEventBus
. You'll need to make sure that your object shares anEventBus
instance with the event producers.
To listen for a common event supertype (such as EventObject
or Object
)...
- ...in traditional Java events: not easy.
-
...with
EventBus
: events are automatically dispatched to listeners of any supertype, allowing listeners for interface types or "wildcard listeners" forObject
.
To listen for and detect events that were dispatched without listeners...
- ...in traditional Java events: add code to each event-dispatching method (perhaps using AOP).
-
...with
EventBus
: subscribe toDeadEvent
. TheEventBus
will notify you of any events that were posted but not delivered. (Handy for debugging.)
For Producers
To keep track of listeners to your events...
-
...in traditional Java events: write code to manage a list of listeners to your object, including synchronization, or use a utility class like
EventListenerList
. -
...with
EventBus
:EventBus
does this for you.
To dispatch an event to listeners...
- ...in traditional Java events: write a method to dispatch events to each event listener, including error isolation and (if desired) asynchronicity.
-
...with
EventBus
: pass the event object to anEventBus
'sEventBus.post(Object)
method.
Glossary
The EventBus
system and code use the following terms to discuss event distribution:
Event | Any object that may be posted to a bus. |
---|---|
Subscribing | The act of registering a listener with an EventBus , so that its handler methods will receive events. |
Listener | An object that wishes to receive events, by exposing handler methods. |
Handler method | A public method that the EventBus should use to deliver posted events. Handler methods are marked by the @Subscribe annotation. |
Posting an event | Making the event available to any listeners through the EventBus . |
例子
public class TGuavaEventBus {
// 消息? 事件?
static class TestEvent{
private final int message;
public TestEvent(int message) {
this.message = message;
}
public int getMessage() {
return message;
}
}
static class TestEvent2{
private final String message;
public TestEvent2(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
static class EventListener {
private String name;
public int intMsg = 0;
public EventListener(String aname){
name = aname;
}
@Subscribe
public void listenInt(TestEvent event) {
intMsg = event.getMessage();
System.out.println(name + " receive a Message:"+ intMsg);
}
@Subscribe
public void listenInt2(TestEvent event) {
intMsg = event.getMessage();
System.out.println(name + "receive b Message:"+ intMsg);
}
}
static class EventListener2 {
private String name;
public int intMsg = 0;
public String strMsg;
public EventListener2(String aname){
name = aname;
}
// 消息的接收,是按照消息类型判断的,与方法名无关
@Subscribe
public void listen(TestEvent event) {
intMsg = event.getMessage();
System.out.println(name + "receive int Message:"+intMsg);
}
@Subscribe
public void listenStr(TestEvent2 event) {
strMsg = event.getMessage();
System.out.println(name + " receive str Message:"+strMsg);
}
}
static class Productor1{
private final int num;
private final String message;
public Productor1(int anum, String amessage){
num = anum;
message = amessage;
}
public void doBusi1(){
System.out.println("-----------doBusi1---"+message);
eventBus1.post(new TestEvent(num));
eventBus1.post(new TestEvent2(message));
System.out.println("-----------doBusi1---"+message);
}
public void doBusi2(){
System.out.println("-----------doBusi2---"+message);
eventBus2.post(new TestEvent(num));
eventBus2.post(new TestEvent2(message));
System.out.println("-----------doBusi2---"+message);
}
public void doBusi3(){
System.out.println("-----------doBusi3---"+message);
eventBus1.post(new TestEvent(num));
System.out.println("----11------");
eventBus2.post(new TestEvent(num));
System.out.println("----22------");
eventBus1.post(new TestEvent2(message));
System.out.println("----33------");
eventBus2.post(new TestEvent2(message));
System.out.println("-----------doBusi3---"+message);
}
}
private static EventBus eventBus1 = new EventBus("eventBus_1");
private static EventBus eventBus2 = new EventBus("eventBus_2");
public static void testReceiveEvent(){
Productor1 pdt1 = new Productor1(1, "product_1");
Productor1 pdt2 = new Productor1(2, "product_2");
Productor1 pdt3 = new Productor1(3, "product_3");
EventListener listener1_1 = new EventListener("listen1_1");
EventListener listener1_2 = new EventListener("listen1_2");
eventBus1.register(listener1_1);
eventBus1.register(listener1_2);
EventListener2 listener2_1 = new EventListener2("listen2_1");
eventBus2.register(listener2_1);
pdt1.doBusi1();
pdt2.doBusi2();
pdt3.doBusi3();
}
}