在说清楚spring的事件传播器之前,先回顾下spring的事件监听机制
一、事件监听
public class TestEvent extends ApplicationEvent { private String message; public TestEvent(Object source) { super(source); } public TestEvent(Object source,String message) { super(source); this.message=message; } public void print(){ System.out.println(message); } }public class TestListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationEvent applicationEvent) { if(applicationEvent instanceof TestEvent){ TestEvent testEvent=(TestEvent)applicationEvent; testEvent.print(); } } }<bean id="testListener" class="com.springboot2.test.TestListener"></bean>ApplicationContext sc=new ClassPathXmlApplicationContext("beans.xml"); TestEvent testEvent = new TestEvent("hello", "spring"); sc.publishEvent(testEvent);
二、源码分析
1、事件广播
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
} else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No 'applicationEventMulticaster' bean, using [" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
按照之前介绍的顺序和逻辑,作为广播器,一定是用于存放监听器并在合适的时候调用监听器。
SimpleApplicationEventMulticaster是默认的广播实现,查看该默认的广播器中multicastEvent方法
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) { ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event); Executor executor = this.getTaskExecutor(); Iterator var5 = this.getApplicationListeners(event, type).iterator(); while(var5.hasNext()) { ApplicationListener<?> listener = (ApplicationListener)var5.next(); if (executor != null) { executor.execute(() -> { this.invokeListener(listener, event); }); } else { this.invokeListener(listener, event); } } }
当spring产生事件时候会默认使用SimpleApplicationEventMulticaster的multicastEvent方法来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent进行监听器的处理。对于每一个监听器而言,其实都可以获取到spring的事件,但是是否需要处理,是由具体的监听器来决定。
2、注册监听器
protected void registerListeners() {
Iterator var1 = this.getApplicationListeners().iterator();
//硬编码方式注册监听器
while(var1.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var1.next();
this.getApplicationEventMulticaster().addApplicationListener(listener);
}//配置文件注册监听器
String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
String[] var7 = listenerBeanNames;
int var3 = listenerBeanNames.length;for(int var4 = 0; var4 < var3; ++var4) {
String listenerBeanName = var7[var4];
this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
Iterator var9 = earlyEventsToProcess.iterator();while(var9.hasNext()) {
ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}}
注册监听器有两个途径:编码注册,配置文件注册