|
Java example source code file (package-info.java)
The package-info.java Java example source code/* * Copyright (C) 2007 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ /** * The EventBus allows publish-subscribe-style communication between components without requiring * the components to explicitly register with one another (and thus be aware of each other). It is * designed exclusively to replace traditional Java in-process event distribution using explicit * registration. It is <em>not a general-purpose publish-subscribe system, nor is it intended * for interprocess communication. * * <p>See the Guava User Guide article on * <a href="https://github.com/google/guava/wiki/EventBusExplained">{@code EventBus}. * * <h2>One-Minute Guide * * <p>Converting an existing EventListener-based system to use the EventBus is easy. * * <h3>For Listeners * * <p>To listen for a specific flavor of event (say, a CustomerChangeEvent)... * <ul> * <li>...in traditional Java events: implement an interface defined with the event * — such as CustomerChangeEventListener. * <li>...with EventBus: create a method that accepts CustomerChangeEvent as its * sole argument, and mark it with the {@link com.google.common.eventbus.Subscribe} * annotation. * </ul> * * <p>To register your listener methods with the event producers... * <ul> * <li>...in traditional Java events: pass your object to each producer's * {@code registerCustomerChangeEventListener} method. These methods are rarely defined in * common interfaces, so in addition to knowing every possible producer, you must also know its * type. * <li>...with EventBus: pass your object to the * {@link com.google.common.eventbus.EventBus#register(Object)} method on an EventBus. You'll * need to make sure that your object shares an EventBus instance with the event producers. * </ul> * * <p>To listen for a common event supertype (such as EventObject or Object)... * <ul> * <li>...in traditional Java events: not easy. * <li>...with EventBus: events are automatically dispatched to listeners of any * supertype, allowing listeners for interface types or "wildcard listeners" for Object. * </ul> * * <p>To listen for and detect events that were dispatched without listeners... * <ul> * <li>...in traditional Java events: add code to each event-dispatching method * (perhaps using AOP). * <li>...with EventBus: subscribe to {@link com.google.common.eventbus.DeadEvent}. * The EventBus will notify you of any events that were posted but not delivered. (Handy for * debugging.) * </ul> * * <h3>For Producers * * <p>To keep track of listeners to your events... * <ul> * <li>...in traditional Java events: write code to manage a list of listeners to * your object, including synchronization, or use a utility class like EventListenerList. * <li>...with EventBus: EventBus does this for you. * </ul> * * <p>To dispatch an event to listeners... * <ul> * <li>...in traditional Java events: write a method to dispatch events to each * event listener, including error isolation and (if desired) asynchronicity. * <li>...with EventBus: pass the event object to an EventBus's * {@link com.google.common.eventbus.EventBus#post(Object)} method. * </ul> * * <h2>Glossary * * <p>The EventBus system and code use the following terms to discuss event distribution: * <dl> * * <dt>Event * <dd>Any object that may be posted to a bus. * * <dt>Subscribing * <dd>The act of registering a listener with an EventBus, so that its * <em>subscriber methods will receive events. * * <dt>Listener * <dd>An object that wishes to receive events, by exposing subscriber methods. * * <dt>Subscriber method * <dd>A public method that the EventBus should use to deliver posted events. Subscriber * methods are marked by the {@link com.google.common.eventbus.Subscribe} annotation. * * <dt>Posting an event * <dd>Making the event available to any listeners through the EventBus. * * </dl> * * <h2>FAQ * <h3>Why must I create my own Event Bus, rather than using a singleton? * * <p>The Event Bus doesn't specify how you use it; there's nothing stopping your application from * having separate EventBus instances for each component, or using separate instances to separate * events by context or topic. This also makes it trivial to set up and tear down EventBus objects * in your tests. * * <p>Of course, if you'd like to have a process-wide EventBus singleton, there's nothing stopping * you from doing it that way. Simply have your container (such as Guice) create the EventBus as a * singleton at global scope (or stash it in a static field, if you're into that sort of thing). * * <p>In short, the EventBus is not a singleton because we'd rather not make that decision for you. * Use it how you like. * * <h3>Why use an annotation to mark subscriber methods, rather than requiring the listener to * implement an interface?</h3> * * <p>We feel that the Event Bus's {@code @Subscribe} annotation conveys your intentions just as * explicitly as implementing an interface (or perhaps more so), while leaving you free to place * event subscriber methods wherever you wish and give them intention-revealing names. * * <p>Traditional Java Events use a listener interface which typically sports only a handful of * methods -- typically one. This has a number of disadvantages: * <ul> * <li>Any one class can only implement a single response to a given event. * <li>Listener interface methods may conflict. * <li>The method must be named after the event (e.g. {@code handleChangeEvent}), rather than its * purpose (e.g. {@code recordChangeInJournal}). * <li>Each event usually has its own interface, without a common parent interface for a family of * events (e.g. all UI events). * </ul> * * <p>The difficulties in implementing this cleanly has given rise to a pattern, particularly common * in Swing apps, of using tiny anonymous classes to implement event listener interfaces. * * <p>Compare these two cases:{@code * class ChangeRecorder { * void setCustomer(Customer cust) { * cust.addChangeListener(new ChangeListener() { * void customerChanged(ChangeEvent e) { * recordChange(e.getChange()); * } * }; * } * } * * // Class is typically registered by the container. * class EventBusChangeRecorder { * }{@code @Subscribe void recordCustomerChange(ChangeEvent e) { * recordChange(e.getChange()); * } * }}</pre> * * <p>The intent is actually clearer in the second case: there's less noise code, and the event * subscriber has a clear and meaningful name. * * <h3>What about a generic {@code Subscriber |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.