目录
发布订阅模式,Event事件驱动实现
Google EventBus 和 GreenRobot 实现逻辑是一样的,只是接口方式不一样
一、逻辑分析
二、Google EventBus
- 依赖引入
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
- EventConfig
@Configuration
public class EventConfig {
// 同步
@Bean
public EventBus eventBus() {
return new EventBus();
}
// 异步
@Bean
public AsyncEventBus asyncEventBus() {
return new AsyncEventBus(Executors.newFixedThreadPool(10));
}
}
- MyEvent
public class MyEvent implements Serializable {
private static final long SerializableUID = 1;
private String name;
private String event;
private String message;
public MyEvent(String name, String event, String message) {
this.name = name;
this.event = event;
this.message = message;
}
// get set ...
}
- MyListener
为了能够测试同步和异步的差别,需要构造两个Listener来进行处理。
- MyListenerOne
@Component
public class MyListenerOne {
Logger logger = LoggerFactory.getLogger(MyListenerOne.class);
@Subscribe
public void One(MyEvent myEvent) throws InterruptedException {
logger.info("One-One:event=" + myEvent);
Thread.sleep(3000L);
}
@Subscribe
public void Two(MyEvent event) throws InterruptedException {
logger.info("One-Two:event=" + myEvent);
Thread.sleep(3000L);
}
}
- MyListenerTwo
@Component
public class MyListenerTwo {
Logger logger = LoggerFactory.getLogger( MyListenerTwo.class);
@Subscribe
public void One(MyEvent myEvent) throws InterruptedException {
logger.info("Two-One:event=" + myEvent);
Thread.sleep(3000L);
}
@Subscribe
public void Two(MyEvent event) throws InterruptedException {
logger.info("Two-Two:event=" + myEvent);
Thread.sleep(3000L);
}
}
- EventHandler
@Component
public class EventHandler {
Logger logger = LoggerFactory.getLogger(EventHandler.class);
@Autowired
EventBus eventBus;
@Autowired
MyListenerOne myListenerOne;
@Autowired
MyListenerTwo myListenerTwo;
@PostConstruct
public void init() {
eventBus.register(myListenerOne);
eventBus.register(myListenerTwo);
asyncEventBus.register(myListenerOne);
asyncEventBus.register(myListenerTwo);
}
@PreDestroy
public void destroy() {
eventBus.unregister(myListenerOne);
eventBus.unregister(myListenerTwo);
asyncEventBus.unregister(myListenerOne);
asyncEventBus.unregister(myListenerTwo);
}
public void eventPost(Object obj) throws InterruptedException {
logger.info("post message begin!");
eventBus.post(obj);
logger.info("post message end!");
logger.info("async post message begin!");
asyncEventBus.post(obj);
logger.info("async post message end!");
}
}
- 调用
@RestController
public class EventController {
@Autowired
EventHandler eventHandler;
@GetMapping("/eventPost")
public String eventPost() throws InterruptedException {
MyEvent myEvent = new MyEvent("eventPost", "MyEvent", "From Google");
eventHandler.glEventPost(myEvent);
return "OK";
}
}
- 结果分析:
1、每个Event 都会睡眠 3秒
同步操作下,主线程会按照顺序执行过程中的每个方法。每个方法执行完后等待 3秒 ,执行下一个,等待所有方法执行完,才打印结束
异步操作下,主线程会直接打印结束,子线程执行该过程中需要执行的方法
2、异步操作下,子线程执行的方法也是会进行等待的,但是由于线程数比执行的方法多,就不会存在队列等待的问题。
设置的多线程为 2个时,执行的 4 个方法时,后两个就会等待前两个释放才执行,也是等待3秒后触发。
三、GreenRobot EventBus
官网介绍:EventBus: Events for Android - Open Source by greenrobot
- 依赖引入
<dependency>
<groupId>org.greenrobot</groupId>
<artifactId>eventbus</artifactId>
<version>3.2.0</version>
</dependency>
- EventConfig
和 Google EventBus 的对象创建不一样。
@Configuration
public class EventConfig {
@Bean
public EventBus eventBus() {
return EventBus.getDefault();
}
}
- MyEvent
复用 google的 Event 对象。
public class MyEvent implements Serializable {
private static final long SerializableUID = 1;
private String name;
private String event;
private String message;
public MyEvent(String name, String event, String message) {
this.name = name;
this.event = event;
this.message = message;
}
// get set ...
}
- MyListener
为了能够测试同步和异步的差别,需要构造两个Listener来进行处理。
注意 @Subscribe 注解 和 Google是不通用的,底层实现不一样。
- MySyncListener
@Component
public class MySyncListener {
Logger logger = LoggerFactory.getLogger(MySyncListener.class);
@Subscribe
public void syncOne(MyEvent myEvent) throws InterruptedException {
logger.info("sync:One=" + myEvent);
Thread.sleep(3000L);
}
@Subscribe
public void syncTwo(MyEvent myEvent) throws InterruptedException {
logger.info("sync:two=" + myEvent);
Thread.sleep(3000L);
}
}
- MyAsyncListener
@Component
public class MyAsyncListener {
Logger logger = LoggerFactory.getLogger(MyAsyncListener.class);
@Subscribe(threadMode = ThreadMode.ASYNC)
public void aSyncOne(MyEvent myEvent) throws InterruptedException {
logger.info("aSync:One=" + myEvent);
Thread.sleep(3000L);
}
@Subscribe(threadMode = ThreadMode.ASYNC)
public void aSyncTwo(MyEvent myEvent) throws InterruptedException {
logger.info("aSync:two=" + myEvent);
Thread.sleep(3000L);
}
}
- EventHandler
@Component
public class EventHandler {
Logger logger = LoggerFactory.getLogger(EventHandler.class);
@Autowired
EventBus eventBus;
@Autowired
MySyncListener mySyncListener;
@Autowired
MyAsyncListener myAsyncListener;
@PostConstruct
public void init() {
grEventBus.register(myAsyncListener);
grEventBus.register(mySyncListener);
}
@PreDestroy
public void destroy() {
grEventBus.unregister(myAsyncListener);
grEventBus.unregister(mySyncListener);
}
public void eventPost(Object obj) throws InterruptedException {
logger.info("post message begin!");
grEventBus.post(obj);
logger.info("post message end!");
}
}
- 调用
@RestController
public class EventController {
@Autowired
EventHandler eventHandler;
@GetMapping("/eventPost")
public String eventPost() throws InterruptedException {
MyEvent myEvent = new MyEvent("eventPost", "MyEvent", "From GreenRobot");
eventHandler.glEventPost(myEvent);
return "OK";
}
}
- 结果分析
下发会根据注册的所有事件直接指派,就会出现 同步和异步同时收到并且执行的情况。主线程和异步是用的不同的线程池。