eventBus的作用
解耦两段直接调用的业务逻辑。比如有两个对象A、B,假如A的值发生改变的话相应的B也需要发生改变。用EventBus(事件总线)将这两个对象进行联系。
EventBus包含三个对象
Event - 事件对象
poster - 生产者
subscriber - 消费者
在这个例子中,A就可以当作生产者,B就可以当中消费者。A的改变就为一个事件,A把事件post(分发)到EventBus(事件总线),B就可以通过EventBus获取事件从而做出应答。
springBoot集成EventBus实例
创建spring项目
1、导入依赖
<!--实现事件总线依赖--> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>28.0-jre</version> </dependency>
2、创建被监听类 UserEvent - 任何类都可被监听
public class UserEvent { private String name; private Integer age;......
3、创建监听类对象 Listener1
监听类中的监听方法需要被@Subscribe注解修饰表示这是一个监听方法,且被监听对象做为方法参数传入
public class Listener1 { /** * 监听方法 * @Subscribe 注解表示这是一个监听方法 * @param userEvent 被监听对象 */ @Subscribe public void listen1(UserEvent userEvent){ //打印被监听对象 System.out.println("监听器1的线程"+Thread.currentThread().getName()+"监听:"+userEvent+"对象"); } @Subscribe public void listen2(UserEvent userEvent){ //打印被监听对象 System.out.println("监听器1的线程"+Thread.currentThread().getName()+"监听:"+userEvent+"对象"); } }
4、创建事件总线工具类 EventBusUtil
public class EventBusUtil { /** * 创建事件总线对象 */ private static EventBus eventBus = new EventBus(); /** * 创建异步总线对象 * 异步总线对象对每一个新的发布都采用新的线程,所以需要注入线程池供其使用 */ private static AsyncEventBus asyncEventBus = new AsyncEventBus(Executors.newCachedThreadPool()); /** * 注册监听器 * @param listener 监听器对象 */ public static void register(Object listener){ eventBus.register(listener); asyncEventBus.register(listener); } /** * 发布事件 * @param event */ public static void post(Object event){ eventBus.post(event); } /** * 异步发布事件 * @param event */ public static void asyncPost(Object event){ asyncEventBus.post(event); } }
其中EventBus为同步总线对象,AsyncEventBus为异步总线对象。
这两个对象的区别为:
1)EventBus处理post请求是单线程(当前线程),处理顺序与监听器对象的注册顺序有关,且当监听器对象全部处理请求完毕前,不会执行后面的代码。
2)AsyncEventBus是异步请求方式,每处理一个监听器的请求就会创建一个新的线程来处理,所以在创建AsyncEventBus对象时需要注入线程池到其构造方法。所有监听器一起工作(宏观),且在所有监听请求处理完成前主线程可以继续执行后面的代码。
AsyncEventBus继承于EventBus
所以EventBus中的post方法:发布事件,register方法:注册监听器。AsyncEventBus使用也是一样。
5、测试同步发布事件
/**测试发布事件*/ @Test public void testPost(){ //创建被监听对象 UserEvent userEvent = new UserEvent("张三",18); //创建监听器对象 Listener1 listener1 = new Listener1(); Listener2 listener2 = new Listener2(); //注册监听器对象 EventBusUtil.register(listener1); EventBusUtil.register(listener2); //发布事件 EventBusUtil.post(userEvent); //同步发布需要等监听器都执行完毕才执行下面代码 System.out.println(Thread.currentThread().getName()+"线程执行完毕 over"); }
执行结果 - 单线程有序
监听器1的线程main监听:UserEvent{name='张三', age=18}对象
监听器1的线程main监听:UserEvent{name='张三', age=18}对象
监听器2的线程main监听:UserEvent{name='张三', age=18}对象
main线程执行完毕 over
6、测试异步发布事件
/**测试异步发布事件*/ @Test public void testAsyncPost(){ UserEvent userEvent = new UserEvent("张三",18); UserEvent userEvent2 = new UserEvent("李四", 20); //创建监听器对象 Listener1 listener1 = new Listener1(); Listener2 listener2 = new Listener2(); //注册监听器对象 EventBusUtil.register(listener1); EventBusUtil.register(listener2); //异步发布事件 EventBusUtil.asyncPost(userEvent); //异步发布不需要等监听器都执行完毕才执行下面代码 System.out.println(Thread.currentThread().getName()+"线程执行完毕 over"); }
执行结果 - 多线程异步无序
main线程执行完毕 over
监听器1的线程pool-1-thread-2监听:UserEvent{name='张三', age=18}对象
监听器1的线程pool-1-thread-1监听:UserEvent{name='张三', age=18}对象
监听器2的线程pool-1-thread-3监听:UserEvent{name='张三', age=18}对象