Starter
Step
1. 引入pom依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
2. 定义事件
public class BaseEvent {
public static final TimeZone DEFAULT_TIME_ZONE = TimeZone.getTimeZone("GMT+8");
private String eventId;
private LocalDateTime eventTime;
private Object target;
public BaseEvent() {
this(UUID.randomUUID().toString(), LocalDateTime.now(DEFAULT_TIME_ZONE.toZoneId()), null);
}
public BaseEvent(String eventId, LocalDateTime eventTime, Object target) {
this.eventId = eventId;
this.eventTime = eventTime;
this.target = target;
}
public <R extends BaseEvent> R eventId(String eventId) {
this.eventId = eventId;
return (R) this;
}
public <R extends BaseEvent> R eventTime(LocalDateTime eventTime) {
this.eventTime = eventTime;
return (R) this;
}
public <R extends BaseEvent> R eventTime(Object target) {
this.target = target;
return (R) this;
}
public String getEventId() {
return eventId;
}
public void setEventId(String eventId) {
this.eventId = eventId;
}
public LocalDateTime getEventTime() {
return eventTime;
}
public void setEventTime(LocalDateTime eventTime) {
this.eventTime = eventTime;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
}
@Data
@Builder
public class LogEvent extends BaseEvent {
private String msg;
private String traceId;
}
3.事件操作接口
public interface BusOperation {
void register(EventListener eventListener);
BusOperation pushEvent(BaseEvent event);
}
public class EventBusImpl implements BusOperation, Closeable {
private List<EventListener> eventListeners = new ArrayList<>();
private EventBus eventBus;
private ExecutorService executorService;
public static EventBusImpl now() {
EventBusImpl eventBusTemplate = new EventBusImpl();
eventBusTemplate.syncEventBus(new EventBus());
return eventBusTemplate;
}
private void syncEventBus(EventBus eventBus) {
this.eventBus = eventBus;
}
public EventBus asyncEventBus(ExecutorService executorService) {
this.eventBus = new AsyncEventBus(executorService);
this.executorService = executorService;
return this.eventBus;
}
@Override
public void register(EventListener eventListener) {
eventBus.register(eventListener);
if (!eventListeners.contains(eventListener)) {
eventListeners.add(eventListener);
}
}
@Override
public BusOperation pushEvent(BaseEvent event) {
eventBus.post(event);
return this;
}
public void setEventListeners(List<EventListener> eventListeners) {
Assert.notEmpty(eventListeners, "监听器列表不为空");
Assert.noNullElements(eventListeners, "监听器列表中元素不能为空");
if (this.eventListeners != eventListeners) {
this.eventListeners.clear();
this.eventListeners.addAll(eventListeners);
}
eventListeners.forEach(eventListener -> {
this.register(eventListener);
});
}
@Override
public void close() throws WebServiceException {
if (executorService != null && !executorService.isShutdown()) {
executorService.isShutdown();
}
}
}
4. 定义EventListener接口
public interface EventListener {
void consumerEvent(BaseEvent event);
}
@Component
@Slf4j
public class LogEventListener implements EventListener {
@Subscribe
@Override
public void consumerEvent(BaseEvent event) {
log.info("LogEventListener: {}", event);
}
}
@Component
@Slf4j
public class SaveLogEventListener implements EventListener {
@Subscribe
@Override
public void consumerEvent(BaseEvent event) {
log.info("SaveLogEventListener: {}", event);
}
}
5. 定义配置接口
@Configuration
public class EventBusConfig {
@Autowired
private ApplicationContext applicationContext;
@Value("${eventbus.thread.corepoolsize:20}")
private int corePoolSize;
private static final String EVENT_BUS_THREAD_NAME = "MyEventBusT";
@Bean
public EventBusImpl eventBusTemplate() {
EventBusImpl eventBusTemplate = EventBusImpl.now();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, corePoolSize, 0L,
TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>(), new ThreadFactory() {
private AtomicInteger threadIndex = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, String.join("_", EVENT_BUS_THREAD_NAME, String.valueOf(this.threadIndex.incrementAndGet())));
}
}, new ThreadPoolExecutor.CallerRunsPolicy());
eventBusTemplate.asyncEventBus(threadPoolExecutor);
Map<String, EventListener> matchEventListener = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, EventListener.class, true, false);
if (!matchEventListener.isEmpty()) {
eventBusTemplate.setEventListeners(Lists.newArrayList(matchEventListener.values()));
}
return eventBusTemplate;
}
}
6. 测试
@SpringBootTest
@Slf4j
public class EventBusTest {
@Autowired
private EventBusImpl eventBus;
@Test
public void testPush() throws InterruptedException {
for (int i = 0; i < 10; i++) {
LogEvent logEvent = LogEvent.builder().traceId(UUID.randomUUID().toString())
.msg("test\t" + i).build();
eventBusTemplate.pushEvent(logEvent);
}
TimeUnit.SECONDS.sleep(10);
}
}