我們想停掉壹個spring的進程,壹般通過kill命令完成,常用的命令如 kill -2 pid(ctrl + C) 、 kill -9 pid 、 kill -15 pid 。
kill -9 可以認為操作系統從內核級別直接強行kill進程,對服務來說沒有任何的準備時間和清場時間,直接被kill掉,且無法被監聽。
kill -2 和 -15 則是操作系統給該進程發送壹個信號通知,告知應用主動關閉,應用可以監聽並接收到信號,可以完成壹些關閉回收等動作,然後自我停止。
準確來說,這些關閉信號並不是由spring感知,而是由java線程 Signal Dispatcher 監聽,此線程將收到的信號交給JVM,JVM判斷信號種類,如果是-2/-15等關閉類型,則交由 java.lang.Shutdown 完成關閉,關閉前會觸發所有的shutdown hook。
Runtime.getRuntime().addShutdownHook() 可以添加自定義的shutdown hook。
關於jvm關閉詳細的原理分析過程請參考 java進程關閉事件監聽
spring在啟動過程中也是通過 Runtime.getRuntime().addShutdownHook() 來註冊hook回調。
SpringApplication
在 SpringApplication 的 run 方法中,會調用 refreshContext ,默認情況下會調用 context.registerShutdownHook();
AbstractApplicationContext
在 AbstractApplicationContext. registerShutdownHook() ,實現了添加shutdown hook,對應的回調實現為 doClose() ;
其中 發布ContextClosedEvent事件 是非常關鍵的壹步,所有希望完成清場操作的業務或組件都可以監聽此事件來完成觸發。
整個回收過程還是比較簡單的。