深入理解Spring IOC之扩展篇(十)、SpringBoot中重要event介绍,顺便简单讲下SB的启动流程(二)

549 阅读2分钟

上一篇我们讲到了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注入配置,不要以为这不可能,因为我们公司有大神就是这么做的,所以说思路在某种成都上比源码更重要。