EventBus:
创建EventBus实例:
EventBus eventBus = new EventBus();//或者EventBus eventBus = new EventBus(TradeAccountEvent.class.getName());//带标识符,用于日志记录
订阅事件:
- 模拟一个交易过程。
- 事件类:
/** * 事件类 */public class TradeAccountEvent { private double amount; private Date tradeExecutionTime; private TradeType tradeType; private TradeAccount tradeAccount; public TradeAccountEvent(TradeAccount account, double amount, Date tradeExecutionTime, TradeType tradeType) { this.amount = amount; this.tradeExecutionTime = tradeExecutionTime; this.tradeAccount = account; this.tradeType = tradeType; }}/** * 购买事件 */public class BuyEvent extends TradeAccountEvent { public BuyEvent(TradeAccount tradeAccount, double amount, Date tradExecutionTime) { super(tradeAccount, amount, tradExecutionTime, TradeType.BUY); }}/** * 卖出事件 */public class SellEvent extends TradeAccountEvent { public SellEvent(TradeAccount tradeAccount, double amount, Date tradExecutionTime) { super(tradeAccount, amount, tradExecutionTime, TradeType.SELL); }}
- 订阅者
/** * 卖出和购买审计,即订阅者 */public class AllTradesAuditor { private ListbuyEvents = Lists.newArrayList(); private List sellEvents = Lists.newArrayList(); public AllTradesAuditor(EventBus eventBus) { eventBus.register(this); } /** * 订阅卖出事件 */ @Subscribe public void auditSell(SellEvent sellEvent) { sellEvents.add(sellEvent); System.out.println("Received TradeSellEvent " + sellEvent); } /** * 订阅购买事件 */ @Subscribe public void auditBuy(BuyEvent buyEvent) { buyEvents.add(buyEvent); System.out.println("Received TradeBuyEvent " + buyEvent); }}
- 发布者
/** * 执行交易, 即发布者 */public class SimpleTradeExecutor { private EventBus eventBus; public SimpleTradeExecutor(EventBus eventBus) { this.eventBus = eventBus; } /** * 执行交易 */ public void executeTrade(TradeAccount tradeAccount, double amount, TradeType tradeType) { TradeAccountEvent tradeAccountEvent = processTrade(tradeAccount, amount, tradeType); eventBus.post(tradeAccountEvent); // 发布事件 } /** * 处理交易 * * @return 交易事件 */ private TradeAccountEvent processTrade(TradeAccount tradeAccount, double amount, TradeType tradeType) { Date executionTime = new Date(); String message = String.format( "Processed trade for %s of amount %n type %s @ %s", tradeAccount, amount, tradeType, executionTime); TradeAccountEvent tradeAccountEvent; if (tradeType.equals(TradeType.BUY)) { //购买动作 tradeAccountEvent = new BuyEvent(tradeAccount, amount, executionTime); } else { //卖出动作 tradeAccountEvent = new SellEvent(tradeAccount, amount, executionTime); } System.out.println(message); return tradeAccountEvent; }}
- 测试用例
EventBus eventBus = new EventBus();AllTradesAuditor auditor = new AllTradesAuditor(eventBus);SimpleTradeExecutor tradeExecutor = new SimpleTradeExecutor(eventBus);tradeExecutor.executeTrade(new TradeAccount(), 1000, TradeType.SELL);tradeExecutor.executeTrade(new TradeAccount(), 2000, TradeType.BUY);
取消订阅:
- 订阅者来取消注册
public void unregister(){ this.eventBus.unregister(this);}
AsyncEventBus类
- 闻其名,就是异步事件总线,当处理耗时的处理时很有用,我们要依赖Executors来实现异步事件总线
AsyncEventBus asyncEventBus = new AsyncEventBus(executorService);
DeadEvents:
- 当总线接收到发布者发布的信息时,但这时没有订阅者,那么该事件会被包装为DeadEvent事件
public class DeadEventSubscriber { private static final Logger logger = Logger.getLogger(DeadEventSubscriber.class.getName()); public DeadEventSubscriber(EventBus eventBus) { eventBus.register(this); } /** * 没有订阅者时被触发 */ @Subscribe public void handleUnsubscribedEvent(DeadEvent event){ logger.warning("No subscribers for "+event.getEvent()); }}
依赖注入
- 我们可以通过DI框架(Spring或Guice)来注入同样的EventBus
@Componentpublic class SimpleTradeExecutor { private EventBus eventBus; @Autowired public SimpleTradeExecutor(EventBus eventBus) { this.eventBus = checkNotNull(eventBus, "EventBus can't be null"); }}
@Componentpublic class SimpleTradeAuditor { private List以上就介绍了Guava的EventBus。tradeEvents = Lists.newArrayList(); @Autowired public SimpleTradeAuditor(EventBus eventBus){ checkNotNull(eventBus,"EventBus can't be null"); eventBus.register(this); }}
不吝指正。