走近Guava(六): 事件总线EventBus

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 List<BuyEvent> buyEvents = Lists.newArrayList();
	private List<SellEvent> 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
@Component
public class SimpleTradeExecutor {
       private EventBus eventBus;
       @Autowired
       public SimpleTradeExecutor(EventBus eventBus) {
           this.eventBus = checkNotNull(eventBus, "EventBus can't be null");                                             }
}
@Component
public class SimpleTradeAuditor {
       private List<TradeAccountEvent> tradeEvents =
    Lists.newArrayList();
    @Autowired
    public SimpleTradeAuditor(EventBus eventBus){
           checkNotNull(eventBus,"EventBus can't be null");
           eventBus.register(this);
   }
}

以上就介绍了Guava的EventBus。

来源: http://my.oschina.net/indestiny/blog/219421

https://www.yeetrack.com/?p=1171

https://www.yeetrack.com/?p=1173

走近Guava(三): 集合

走近Guava(四): 并发

https://www.yeetrack.com/?p=1176

https://www.yeetrack.com/?p=1177

https://www.yeetrack.com/?p=1178

发表评论

电子邮件地址不会被公开。 必填项已用*标注

(Spamcheck Enabled)