JDK中通过Observer接口和Observable类实现观察者模式, Observer对象是观察者,Observable对象是被观察者.
实现一个简单的观察者模式有以下几步:
这种方式是通过发布者和订阅者之间的显式注册实现的.
 guava的EventBus就是为了取代这种显示注册方式,使组件间有更好的解耦.
 EventBus不适用于进程间通信。
消息封装类: 任意的Java对象均可
public class LogEvent {
	private String log;
	
	// setter、getter
}
消息接收类: 任意的Java对象均可, 只需要在接收方法上添加注解@Subscribe即可
public class LogEventListener {
	@Subscribe
	public void listen(LogEvent log) {
		// handle log
	}
}
消息发布
// 事件总线
EventBus eventBus = new EventBus();
// 事件监听者
LogEventListener logEventListener = new LogEventListener();
// 注册监听
eventBus.register(logEventListener)
// 发布消息
eventBus.post(new LogEvent("测试"));
EventBus中主要包括以下几个角色:
同步发布事件: EventBus.post(Object)
 异步发布事件: AsyncEventBus.post(Object)
guava并未将EventBus设计为单例, 所以可以根据实际情况使用
EventBus会将所有发布后,没有监听者处理的事件包装为DeadEvent, 可以通过监听该类型的消息来检测哪些消息未指明监听者
EventBus中,可以支持同一个监听者监听多个消息,只需要在每个订阅消息的方法上加上@Subscribe注解即可
    @Subscribe  
    public void listenInteger(Integer event) {  
        lastInteger = event; 
        System.out.println("event Integer:"+lastInteger);
    }  
   
    @Subscribe  
    public void listenLong(Long event) {  
        lastLong = event; 
        System.out.println("event Long:"+lastLong);
    }  
在简单情况下,可以将EventBus声明为全局唯一的单例, 并可以通过Spring完成自动注册, 这样将进一步简化使用
示例:
EventBus工厂
public class EventBusFactory {
	private static final EventBusFactory factory = new EventBusFactory();
	private final EventBus eventBus;
	private EventBusFactory() {
		eventBus = new AsyncEventBus("AsyncEventBus", Executors.newFixedThreadPool(5));
	}
	public static final EventBusFactory getDefault() {
		return factory;
	}
	public EventBus eventBus() {
		return eventBus;
	}
}
通过spring自动注册
@Service  
public class EventBusPostProcessor implements BeanPostProcessor {  
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// for each method in the bean
		Method[] methods = bean.getClass().getMethods();
		for (Method method : methods) {
			// check the annotations on that method
			Annotation[] annotations = method.getAnnotations();
			for (Annotation annotation : annotations) {
				// if it contains the Subscribe annotation
				if (annotation.annotationType().equals(Subscribe.class)) {
					// 检查到bean声明了Guava EventBus Subscribe注解, 则自动注册到全局的EventBus上
					EventBusFactory.getDefault().eventBus().register(bean);
					LOGGER.info("Bean " + beanName + "  was subscribed to EventBus");
					// we only need to register once
					return bean;
				}
			}
		}
		return bean;
	}
}
发布消息
EventBusFactory.getDefault().eventBus().post(new LogEvent(log));
通过这种方式,只需要编写监听者即可,无需关心注册