EventBus学习笔记01

253 阅读1分钟

Starter

  • 概述

Step

1. 引入pom依赖

        <dependency>  
            <groupId>com.google.guava</groupId> 
            <artifactId>guava</artifactId>  
            <version>19.0</version>  
        </dependency>  

2. 定义事件

  • 基本事件BaseEvent
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 {
    /**
     * 注册监听
     * @param eventListener
     */
    void register(EventListener eventListener);

    /**
     * 发布事件
     * @param event
     * @return
     */
    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);
}
  • 具体实现
//实现类1
@Component
@Slf4j
public class LogEventListener implements EventListener {

    @Subscribe
    @Override
    public void consumerEvent(BaseEvent event) {
        log.info("LogEventListener: {}", event);
    }
}
//实现类2
@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);
    }
}