在前面讲到了bean的拓展,这篇文章将讲述事件的拓展java
ApplicationListener 是用来监听容器中发生的事件,只要事件发生,就会触发监听器的回调,完成事件驱动模型的开发spring
这里经过两个问题来进行概述,什么是事件?spring是如何实现的?markdown
【1】什么是事件app
事件是能够被控件识别的操做,如按下肯定按钮,选择某个单选按钮或者复选框。每一种控件有本身能够识别的事件,如窗体的加载、单击、双击等事件,编辑框(文本框)的文本改变事,等等。事件有系统事件和用户事件。系统事件由系统激发,如时间每隔24小时,银行储户的存款日期增长一天。用户事件由用户激发,如用户点击按钮,在文本框中显示特定的文本。事件驱动控件执行某项功能。异步
【2】如何实现源码分析
Spring对事件机制也提供了支持,一个事件被发布后,被对应的监听器监听到,执行对应方法。而且Spring内已经提供了许多事件,ApplicationEvent能够说是Spring事件的顶级父类。ApplicationListener 是监听器的顶级接口,事件被触发后,onApplicationEvent方法就会执行测试
若是咱们要写监听器,就要写这个监听器接口的实现类,ApplicationEvent泛型就是咱们要监听的类,因此咱们要监听或者是发布,都是ApplicationEvent及其下面的子事件,经过查看ApplicationEvent类,咱们发现有如下子事件:this
实现步骤:spa
// 启动测试类
@Test
public void TestMain(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
// 本身发布一个事件
applicationContext.publishEvent(new ApplicationEvent("本身发布的事件") {
});
applicationContext.close();
}
// ApplicationListener实现类
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
// 当容器中发布此事件后,该方法会触发
public void onApplicationEvent(ApplicationEvent applicationEvent) {
System.out.println("收到的事件:" + applicationEvent);
}
}
// 配置类
@Configuration
@ComponentScan("listener")
public class AppConfig {
}
复制代码
运行启动类,输出结果以下,如下三点说一下:3d
在上面的案例中,收到了三个事件,分别是:ContextRefreshedEvent
、ContextClosedEvent
以及本身定义的MainTest$1[source=本身发布的事件]
,这几个事件在底层是如何收到的呢?,咱们就经过源码来进行分析,在回掉方法onApplicationEvent打上断点,经过Debug查看源码:
【1】事件发布
经过Debug,咱们能够看到,最早收到ContextRefreshedEvent
事件,下面我们就根据方法调用栈分析ContextRefreshedEvent
如何发布的
容器建立对象,调用refresh()方法——>finishRefresh()方法——>publishEvent()方法,调用getApplicationEventMulticaster()方法获取事件的多播器,也就是派发器
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
Object applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent)event;
} else {
applicationEvent = new PayloadApplicationEvent(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
}
}
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
} else {
// 获取事件的多播器,也就是派发器
this.getApplicationEventMulticaster().multicastEvent((ApplicationEvent)applicationEvent, eventType);
}
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext)this.parent).publishEvent(event, eventType);
} else {
this.parent.publishEvent(event);
}
}
}
复制代码
调用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进行遍历
ApplicationListener<?> listener = (ApplicationListener)var5.next();
// 判断是否能够用executor异步执行,能够的话使用executor进行异步派发
if (executor != null) {
executor.execute(() -> {
this.invokeListener(listener, event);
});
} else {
// 不然同步执行
this.invokeListener(listener, event);
}
}
}
复制代码
执行invokeListener方法,拿到listener回调onApplicationEvent方法
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
// 执行invokeListener方法,拿到listener回调onApplicationEvent方法
listener.onApplicationEvent(event);
} catch (ClassCastException var6) {
String msg = var6.getMessage();
if (msg != null && !this.matchesClassCastMessage(msg, event.getClass())) {
throw var6;
}
Log logger = LogFactory.getLog(this.getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, var6);
}
}
}
复制代码
【2】获取事件派发器getApplicationEventMulticaster
容器建立对象,调用refresh()方法——>initApplicationEventMulticaster()方法,初始化ApplicationEventMulticaster
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
// 从bean工厂中找是否有ID为“applicationEventMulticaster”的组件
if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
// 获取到该组件
this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
} else {
// 若是没有则本身建立一个简单的ApplicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
// 将建立的注册到容器的单实例bean中
beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No 'applicationEventMulticaster' bean, using [" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
复制代码
【3】容器中有哪些监听器
容器建立对象,调用refresh()方法——>registerListeners()方法,注册监听器
protected void registerListeners() {
// 获取全部Listener
Iterator var1 = this.getApplicationListeners().iterator();
while(var1.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var1.next();
this.getApplicationEventMulticaster().addApplicationListener(listener);
}
// 从容器中拿到全部ApplicationListener类型的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];
// 把组件添加到getApplicationEventMulticaster派发器中,注册到派发器中
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);
}
}
}
复制代码
事件发布流程: