生命周期和事件监听
一个应用的启动过程和关闭过程是归属到“ 生命周期 ”这个概念的范畴。
典型的设计是在启动和关闭过程中 会触发一系列的“事件” ,我们只要监听这些事件,就能参与到这个过程中来。
要想监听事件,首先得有事件监听器,就是常说的Listener。 下面就是Spring提供的监听器,如下图01:
按规定所有的监听器都要继承Java提供的EventListener接口,这个接口是一个空的marker接口,其实就是标识一下。
事件一般都有多个,一般也有两种常用解决方法:
要么定义多个监听器接口,一个事件一个接口。
要么一个接口里定义多个方法,一个事件一个方法。
可惜的是,这两种方法Spring都没有采用,仍然只用了一个接口一个方法,那它是如何实现的呢?
相信大家已经看到,监听器接口有一个泛型参数,没错,就是根据泛型参数的不同来区分不同事件的。
这个泛型参数就是事件对象,按规定所有的事件对象都要继承Java提供的EventObject类,如下图02:
Java提供这个类除了有标识作用外,还和事件源有关。 任何事件都会有一个触发者,它就是事件源。 可以认为是事件的起源或来源。
既然所有事件都有,干脆提升到顶级父类里算了。 如下图03:
不同的事件,含义完全不同,所以差别很大,因此,通常一种事件会有属于自己的一种事件对象。
我们只需要看下事件对象有多少种,就能知道事件有多少种。 这种判断方式一般都没有问题。
下面就是和SpringBoot启动有关的所有事件对象类型,如下图04:
一共有七种事件对象,除去一种是处理失败用的,还剩六种。 也就是说我们可以通过六个事件参与到SpringBoot应用的启动中去。
实现事件监听器接口
监听器就是接口,我们首先要实现这些接口,加入处理逻辑。 然后把它们添加到应用中去就行了。
有六种事件对象,我们需要定义六个实现类。
事件对象为Application Starting Event,如下图05:
事件对象为Application EnvironmentPrepared Event,如下图06:
事件对象为Application ContextInitialized Event,如下图07:
事件对象为Application Prepared Event,如下图08:
事件对象为ApplicationStartedEvent,如下图09:
事件对象为Application Ready Event,如下图10:
把这个六个实现类添加到SpringBoot应用中,如下图11:
实现Runner接口
SpringBoot提供了两个Runner接口,如下图1213:
这两个接口主要用于 满足那种应用刚启动好后就需要立马被执行的需求 。如定时任务。
我们也来实现下这两个接口,如下图1415:
有一点需要注意的是,这两个接口的实现类需要作为bean注册到容器中去。
实现Spring容器初始化接口
如果我们需要对Spring容器进行一些自定义的初始化,可以实现这个接口,如下图16:
这个接口的泛型参数其实就是容器对象。
我们也来实现下这个接口,如下图1718:
我们可以多次实现这个接口,需要排序的话可以使用@Order注解或实现Ordered接口。
然后把这些实现类添加到SpringBoot应用中去,如下图19:
启动应用,观察事件触发的次序
启动后首先触发 启动 事件,如下图20:
接着要做的就是 确认环境 , 创建Environment ,然后触发事件,表明环境已经OK了。如下图21:
然后根据环境 创建Spring容器对象 ,创建好后 执行自定义容器初始化 ,如下图22:
初始化完成后,触发事件,表明 容器就已经准备好 了,如下图23:
容器OK之后,就会 加载资源 (主要是注册bean定义),加载完成后,就会触发事件,如下图24:
接着Spring容器就会进行 refresh ,refresh完成之后,其实Spring容器就已经成功启动好了。
这时会触发事件,如下图25:
容器启动好后, 立马就会执行Runner ,如下图26:
Runner执行完后,SpringBoot应用就 真正启动好 了,进入了 正常运行状态 。
这时会触发最后一个事件,如下图27:
我们可以根据需要,在对应的事件里完成自己的需求。
(END)
【玩转SpringBoot】配置文件yml的正确打开姿势
【玩转SpringBoot】用好条件相关注解,开启自动配置之门
【玩转SpringBoot】给自动配置来个整体大揭秘
【玩转SpringBoot】看似复杂的Environment其实很简单
【玩转SpringBoot】翻身做主人,一统web服务器
【玩转SpringBoot】让错误处理重新由web服务器接管
【玩转SpringBoot】SpringBoot应用的启动过程一览表
品Spring:帝国的基石
品Spring:bean定义上梁山
品Spring:实现bean定义时采用的“先进生产力”
品Spring:注解终于“成功上位”
品Spring:能工巧匠们对注解的“加持”
品Spring:SpringBoot和Spring到底有没有本质的不同?
品Spring:负责bean定义注册的两个“排头兵”
品Spring:SpringBoot轻松取胜bean定义注册的“第一阶段”
品Spring:SpringBoot发起bean定义注册的“二次攻坚战”
品Spring:注解之王@Configuration和它的一众“小弟们”
品Spring:bean工厂后处理器的调用规则
品Spring:详细解说bean后处理器
品Spring:对@PostConstruct和@PreDestroy注解的处理方法
品Spring:对@Resource注解的处理方法
品Spring:对@Autowired和@Value注解的处理方法
品Spring:真没想到,三十步才能完成一个bean实例的创建
品Spring:关于@Scheduled定时任务的思考与探索,结果尴尬了
>>> 热门文章集锦 <<<
毕业10年,我有话说
【面试】我是如何面试别人List相关知识的,深度有点长文
我是如何在毕业不久只用1年就升为开发组长的
爸爸又给Spring MVC生了个弟弟叫Spring WebFlux
【面试】我是如何在面试别人Spring事务时“套路”对方的
【面试】Spring事务面试考点吐血整理(建议珍藏)
【面试】我是如何在面试别人Redis相关知识时“软怼”他的
【面试】吃透了这些Redis知识点,面试官一定觉得你很NB(干货 | 建议珍藏)
【面试】如果你这样回答“什么是线程安全”,面试官都会对你刮目相看(建议珍藏)
【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)
【面试】一篇文章帮你彻底搞清楚“I/O多路复用”和“异步I/O”的前世今生(深度好文,建议珍藏)
【面试】如果把线程当作一个人来对待,所有问题都瞬间明白了
Java多线程通关———基础知识挑战
品Spring:帝国的基石
作者 是工作超过 10年 的码农,现在任架构师。喜欢研究技术,崇尚简单快乐。 追求以通俗易懂的语言解说技术,希望所有的读者都能看懂并记住。 下面是公众号的二维码,欢迎关注!