自定义事件发布器
我们如何自己来实现一个事件发布器?
第一步:
定义AbstractApplicationEventMulticaster类实现Spring中的ApplicationEventMulticaster事件发布器接口。先做一个空实现。
abstract static class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster {@Overridepublic void addApplicationListener(ApplicationListener<?> listener) {}@Overridepublic void addApplicationListenerBean(String listenerBeanName) {}@Overridepublic void removeApplicationListener(ApplicationListener<?> listener) {}@Overridepublic void removeApplicationListenerBean(String listenerBeanName) {}@Overridepublic void removeAllListeners() {}@Overridepublic void multicastEvent(ApplicationEvent event) {}@Overridepublic void multicastEvent(ApplicationEvent event, ResolvableType eventType) {}}
第二步:
定义一个线程池。可以让事件发布以多线程方式实现。
@Beanpublic ThreadPoolTaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(10);executor.setMaxPoolSize(20);executor.setQueueCapacity(100);return executor;}
第三步:
往Spring中注入事件发布器对象,返回我们自定义的事件发布器类型,并只要重写两个主要方法。
@Beanpublic ApplicationEventMulticaster applicationEventMulticaster(ConfigurableApplicationContext applicationContext,ThreadPoolTaskExecutor taskExecutor) {return new AbstractApplicationEventMulticaster(){private List<GenericApplicationListener> listeners = new ArrayList<>();@Overridepublic void addApplicationListenerBean(String name) {//搜集事件监听器ApplicationListener listener = applicationContext.getBean(name, ApplicationListener.class);System.out.println(name);ResolvableType type = ResolvableType.forClass(listener.getClass()).getInterfaces()[0].getGeneric();System.out.println(type);//包装原始的事件监听器,变为支持类型检查的事件监听器GenericApplicationListener listener1 = new GenericApplicationListener() {@Overridepublic void onApplicationEvent(ApplicationEvent event) {listener.onApplicationEvent(event);}//是否支持该事件类型@Overridepublic boolean supportsEventType(ResolvableType eventType) {return type.isAssignableFrom(eventType);}};listeners.add(listener1);}@Overridepublic void multicastEvent(ApplicationEvent event, ResolvableType eventType) {for (GenericApplicationListener listener : listeners) {if (listener.supportsEventType(ResolvableType.forClass(event.getClass()))) {taskExecutor.submit(() -> {listener.onApplicationEvent(event);});}}}};}
重写方法的处理:
1.addApplicationListenerBean方法
springBoot启动过程中会往容器中添加所有的监听器,我们可以拿到所有监听器。但是我们需使用泛型监听器类对对原始获取的监听器类进行包装,因为里面可以提供一个判断事件类型的方法,方便后续对事件类型进行处理。
public void addApplicationListenerBean(String name) {//搜集事件监听器ApplicationListener listener = applicationContext.getBean(name, ApplicationListener.class);System.out.println(name);ResolvableType type = ResolvableType.forClass(listener.getClass()).getInterfaces()[0].getGeneric();System.out.println(type);//包装原始的事件监听器,变为支持类型检查的事件监听器GenericApplicationListener listener1 = new GenericApplicationListener() {@Overridepublic void onApplicationEvent(ApplicationEvent event) {listener.onApplicationEvent(event);}//是否支持该事件类型@Overridepublic boolean supportsEventType(ResolvableType eventType) {return type.isAssignableFrom(eventType);}};listeners.add(listener1);}
2.multicastEvent方法
拿到所有包装后的泛型类型的事件监听器,并调用判断事件类型的方法对真实的事件做判断,如果满足条件使用线程池发布事件。
@Overridepublic void multicastEvent(ApplicationEvent event, ResolvableType eventType) {for (GenericApplicationListener listener : listeners) {if (listener.supportsEventType(ResolvableType.forClass(event.getClass()))) {taskExecutor.submit(() -> {listener.onApplicationEvent(event);});}}}
第四步:
总体实现代码如下:
@Configuration
public class TestPublishe {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestPublishe.class);context.getBean(MyService.class).doBusiness();context.close();}static class MyEvent extends ApplicationEvent {public MyEvent(Object source) {super(source);}}@Componentstatic class MyService {private static final Logger log = LoggerFactory.getLogger(TestPublishe.class);@Autowiredprivate ApplicationEventPublisher publisher;public void doBusiness() {log.debug("主线业务");publisher.publishEvent(new MyEvent("MyService.doBusiness()"));}}@Componentstatic class SmsService implements ApplicationListener<MyEvent> {private static final Logger log = LoggerFactory.getLogger(SmsService.class);@Overridepublic void onApplicationEvent(MyEvent event) {log.debug("发送短信");}}@Componentstatic class EmailService implements ApplicationListener<MyEvent> {private static final Logger log = LoggerFactory.getLogger(EmailService.class);@Overridepublic void onApplicationEvent(MyEvent event) {log.debug("发送邮件");}}@Beanpublic ThreadPoolTaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(10);executor.setMaxPoolSize(20);executor.setQueueCapacity(100);return executor;}@Beanpublic ApplicationEventMulticaster applicationEventMulticaster(ConfigurableApplicationContext applicationContext,ThreadPoolTaskExecutor taskExecutor) {return new AbstractApplicationEventMulticaster(){private List<GenericApplicationListener> listeners = new ArrayList<>();@Overridepublic void addApplicationListenerBean(String name) {//搜集事件监听器ApplicationListener listener = applicationContext.getBean(name, ApplicationListener.class);System.out.println(name);ResolvableType type = ResolvableType.forClass(listener.getClass()).getInterfaces()[0].getGeneric();System.out.println(type);//包装原始的事件监听器,变为支持类型检查的事件监听器GenericApplicationListener listener1 = new GenericApplicationListener() {@Overridepublic void onApplicationEvent(ApplicationEvent event) {listener.onApplicationEvent(event);}//是否支持该事件类型@Overridepublic boolean supportsEventType(ResolvableType eventType) {return type.isAssignableFrom(eventType);}};listeners.add(listener1);}@Overridepublic void multicastEvent(ApplicationEvent event, ResolvableType eventType) {for (GenericApplicationListener listener : listeners) {if (listener.supportsEventType(ResolvableType.forClass(event.getClass()))) {taskExecutor.submit(() -> {listener.onApplicationEvent(event);});}}}};}abstract static class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster {@Overridepublic void addApplicationListener(ApplicationListener<?> listener) {}@Overridepublic void addApplicationListenerBean(String listenerBeanName) {}@Overridepublic void removeApplicationListener(ApplicationListener<?> listener) {}@Overridepublic void removeApplicationListenerBean(String listenerBeanName) {}@Overridepublic void removeAllListeners() {}@Overridepublic void multicastEvent(ApplicationEvent event) {}@Overridepublic void multicastEvent(ApplicationEvent event, ResolvableType eventType) {}}
}
输出结果: