上一篇我们讲到了run方法中的prepareContext那里,并且已经讲了四种SpringBoot的事件,接下来我们把这些在本篇讲完.
ApplicationStartedEvent
我们继续来顺着run方法往下看:
// 执行AbstractApplicationContext的refresh方法,即所谓的刷新动作 refreshContext(context); // 刷新之后做的事情,现在是空实现,也就是说其实P都没干 afterRefresh(context, applicationArguments); // 到这里应用已经启动起来了,因此也该调用stopWatch的stop方法了 stopWatch.stop(); // 打印启动成功的日志 if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } // 发布代表启动成功的事件,这也是我们重点关注的 listeners.started(context); // 调用所有的ApplicationRunner和CommandLineRunner类型的bean callRunners(context, applicationArguments);
run方法到这里,难一点的只有refreshContext了,这一步主要也是因为AbstractApplicationContext的refresh方法难,这个方法,可以参考我之前写的深入理解Spring IOC系列,本篇不会去讲这个方法,否则我又得写几万字。我们直接来看我们关注的发布事件这里,其实里面代码还是很简单,我们重点是要明白这个事件发布的意义,这代表着我们的SpringBoot应用已经正儿八经的跑起来了,你可以在这里去做你想做的任何业务上的操作了,比如一些应用系统的初始化动作等。
ApplicationFailedEvent
这个事件是因为我们之前讲过的代码中,任意一个地方抛出了异常,才导致发布这个事件,如果你是去基于SpringBoot去扩展框架,那你应该会关注这个事件,这个在业务场景中应该用的会很少。
ApplicationReadyEvent
事实上这个和ApplicationStartedEvent事件差不多,发布ApplicationStartedEvent到发布ApplicationReadyEvent的之间其实也就调用了ApplicationRunner和CommandLineRunner这两种类型的bean而已,很多时候我们的应用都没有这两种类型的bean。
至此,SpringBoot中几个重要的event就说完了,run方法大概做了什么事情我们也说完了。这里还需要纠正一下上篇文章中有个说的不是很严谨的地方,我上篇文章的结尾说ApplicationPreparedEvent是你可以去拉取配置的最后时机,其实这么说有那么一点不严谨,为什么呢?因为如果你是基于Spring去进行扩展,你是完全可以在AbstractApplicationContext中refresh方法中去拉取,你甚至还能在注入完了再拉取完了单独给bean注入配置,不要以为这不可能,因为我们公司有大神就是这么做的,所以说思路在某种成都上比源码更重要。