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