1. 首页
  2. IT资讯

「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程

“u003Cblockquoteu003Eu003Cpu003E转载:https:u002Fu002Fmp.weixin.qq.comu002Fsu002FmB8pN0o2j08Kq8zXXPCFZQu003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Cpu003Eu003Cstrongu003E生命周期和事件监听u003Cu002Fstrongu003Eu003Cbru002Fu003E一个应用的启动过程和关闭过程是归属到“生命周期”这个概念的范畴。u003Cbru002Fu003E典型的设计是在启动和关闭过程中会触发一系列的“事件”,我们只要监听这些事件,就能参与到这个过程中来。u003Cbru002Fu003E要想监听事件,首先得有事件监听器,就是常说的Listener。下面就是Spring提供的监听器,如下图01:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F9f039abb85f0493f80ac96d891a43f80″ img_width=”720″ img_height=”142″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003Eu003Cbru002Fu003E按规定所有的监听器都要继承Java提供的EventListener接口,这个接口是一个空的marker接口,其实就是标识一下。u003Cbru002Fu003E事件一般都有多个,一般也有两种常用解决方法:u003Cbru002Fu003E要么定义多个监听器接口,一个事件一个接口。u003Cbru002Fu003E要么一个接口里定义多个方法,一个事件一个方法。u003Cbru002Fu003E可惜的是,这两种方法Spring都没有采用,仍然只用了一个接口一个方法,那它是如何实现的呢?u003Cbru002Fu003E相信大家已经看到,监听器接口有一个泛型参数,没错,就是根据泛型参数的不同来区分不同事件的。u003Cbru002Fu003E这个泛型参数就是事件对象,按规定所有的事件对象都要继承Java提供的EventObject类,如下图02:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp9.pstatp.comu002Flargeu002Fpgc-imageu002Fa84c9f054b43441498483ba9f1a6882d” img_width=”510″ img_height=”150″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003EJava提供这个类除了有标识作用外,还和事件源有关。任何事件都会有一个触发者,它就是事件源。可以认为是事件的起源或来源。u003Cbru002Fu003E既然所有事件都有,干脆提升到顶级父类里算了。如下图03:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002F89af44c58651446f85d79e7f51f5c9b3″ img_width=”485″ img_height=”132″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E不同的事件,含义完全不同,所以差别很大,因此,通常一种事件会有属于自己的一种事件对象。u003Cbru002Fu003E我们只需要看下事件对象有多少种,就能知道事件有多少种。这种判断方式一般都没有问题。u003Cbru002Fu003E下面就是和SpringBoot启动有关的所有事件对象类型,如下图04:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F0323258e89e7464d8b4bdf435fab3e73″ img_width=”473″ img_height=”195″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E一共有七种事件对象,除去一种是处理失败用的,还剩六种。也就是说我们可以通过六个事件参与到SpringBoot应用的启动中去。u003Cbru002Fu003Eu003Cstrongu003E实现事件监听器接口u003Cu002Fstrongu003Eu003Cbru002Fu003E监听器就是接口,我们首先要实现这些接口,加入处理逻辑。然后把它们添加到应用中去就行了。u003Cbru002Fu003E有六种事件对象,我们需要定义六个实现类。u003Cbru002Fu003E事件对象为ApplicationStartingEvent,如下图05:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F4eec9da827da4e25bde675cffebfd518″ img_width=”659″ img_height=”158″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E事件对象为ApplicationEnvironmentPreparedEvent,如下图06:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002F4dda2fcae9964e35892ed6ffc3372418″ img_width=”750″ img_height=”156″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E事件对象为ApplicationContextInitializedEvent,如下图07:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F71629057d5ad442eb45d9586711af5d2″ img_width=”742″ img_height=”158″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E事件对象为ApplicationPreparedEvent,如下图08:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F72f2d75e5b034914b7d33799389338a0″ img_width=”684″ img_height=”156″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E事件对象为ApplicationStartedEvent,如下图09:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F2bc5599dd0c642899a0c4767908c7bcf” img_width=”651″ img_height=”155″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E事件对象为ApplicationReadyEvent,如下图10:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002Fbdb926e7c55f4d3e89bf5b2b88231200″ img_width=”637″ img_height=”152″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E把这个六个实现类添加到SpringBoot应用中,如下图11:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F119c6d7cc68642aea4dce1beb6060f13″ img_width=”1025″ img_height=”189″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003Eu003Cstrongu003E实现Runner接口u003Cu002Fstrongu003Eu003Cbru002Fu003ESpringBoot提供了两个Runner接口,如下图1213:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002Fc0309a1e249c4f3c9a8933e0610ed4b9″ img_width=”471″ img_height=”135″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp9.pstatp.comu002Flargeu002Fpgc-imageu002F382fae853e4e47a8b9867d2987ef1a51″ img_width=”411″ img_height=”138″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E这两个接口主要用于满足那种应用刚启动好后就需要立马被执行的需求。如定时任务。u003Cbru002Fu003E我们也来实现下这两个接口,如下图1415:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002F762ed3d73e5646c8bcf96997028c4090″ img_width=”543″ img_height=”173″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F0a6eb592cf3348b9b8de0732a96be41c” img_width=”529″ img_height=”176″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E有一点需要注意的是,这两个接口的实现类需要作为bean注册到容器中去。u003Cbru002Fu003Eu003Cstrongu003E实现Spring容器初始化接口u003Cu002Fstrongu003Eu003Cbru002Fu003E如果我们需要对Spring容器进行一些自定义的初始化,可以实现这个接口,如下图16:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F455bafbe3fb747a385765d74221f85a6″ img_width=”736″ img_height=”121″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E这个接口的泛型参数其实就是容器对象。u003Cbru002Fu003E我们也来实现下这个接口,如下图1718:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp9.pstatp.comu002Flargeu002Fpgc-imageu002F2414dca39a1b4869a78bc9cd5d3f3ad7″ img_width=”787″ img_height=”181″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002F48a9f76501854064b74ac12ab974ab76″ img_width=”788″ img_height=”177″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E我们可以多次实现这个接口,需要排序的话可以使用@Order注解或实现Ordered接口。u003Cbru002Fu003E然后把这些实现类添加到SpringBoot应用中去,如下图19:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F981eea502dc047b7ac15c4e81cab967a” img_width=”685″ img_height=”188″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003Eu003Cstrongu003E启动应用,观察事件触发的次序u003Cu002Fstrongu003Eu003Cbru002Fu003E启动后首先触发启动事件,如下图20:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002F18f25cfda0ba43d4a89549ddfc45c180″ img_width=”518″ img_height=”124″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E接着要做的就是确认环境,创建Environment,然后触发事件,表明环境已经OK了。如下图21:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002F784739642a5f45ffbfd2953264f37d49″ img_width=”416″ img_height=”129″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E然后根据环境创建Spring容器对象,创建好后执行自定义容器初始化,如下图22:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002Fa69bc5aa13d24d7989fcd2f7e083f8e4″ img_width=”541″ img_height=”152″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E初始化完成后,触发事件,表明容器就已经准备好了,如下图23:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002Fc11fb374675e46cea7f12df74f3d8541″ img_width=”501″ img_height=”111″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E容器OK之后,就会加载资源(主要是注册bean定义),加载完成后,就会触发事件,如下图24:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002Fa3859eb6b1964547b232662d38d1f879″ img_width=”444″ img_height=”72″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E接着Spring容器就会进行refresh,refresh完成之后,其实Spring容器就已经成功启动好了。u003Cbru002Fu003E这时会触发事件,如下图25:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002Fab654d06239241db88a397d0aa1df9b7″ img_width=”380″ img_height=”80″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E容器启动好后,立马就会执行Runner,如下图26:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp9.pstatp.comu002Flargeu002Fpgc-imageu002F49e44c0de82f41958175e218f52f52cb” img_width=”450″ img_height=”68″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003ERunner执行完后,SpringBoot应用就真正启动好了,进入了正常运行状态。u003Cbru002Fu003E这时会触发最后一个事件,如下图27:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002Fd07dc6a70b9a402bbf173a7c0d22f73f” img_width=”453″ img_height=”76″ alt=”「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E我们可以根据需要,在对应的事件里完成自己的需求。u003Cu002Fpu003E”

原文始发于:「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程

主题测试文章,只做测试使用。发布者:程序员,转转请注明出处:http://www.cxybcw.com/26430.html

联系我们

13687733322

在线咨询:点击这里给我发消息

邮件:1877088071@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code