日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringBoot 热部署神器快速重启的秘密!

發布時間:2025/3/11 javascript 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot 热部署神器快速重启的秘密! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天咱們來聊聊這個熱部署神器?spring-boot-devtools?的運行原理,看看它是怎么用這個 ClassLoader ?來實現快速重啟,幫我們節省時間的!😝

文章概要

文章的主旋律如下👇


spring.factories

我們直接打開 spring-boot-devtools 源碼 ,找到 spring.factories 文件:


我們一般都本地開發調試的,所以就直接看這個 LocalDevToolsAutoConfiguration 類啦😋

LocalDevToolsAutoConfiguration

可以看到核心點在 重啟和重載 👇


主角👇


我們先來看看這個 重啟 中有什么叭😄

重啟原理介紹

大概這么一個思路👇 下面就跟著源碼分析啦😄(文末有源碼重啟要點流程圖


RestartConfiguration

有這么些方法👇


從名字上分析,這兩個方法應該是重點,邏輯上應該是 有一個 watcher 在盯著 classpath ,如果有變動的話,就觸發這個 ClassPathChangedEvent 事件 😝

那么看看這個 watcher 叭 😄

ClassPathFileSystemWatcher


可以看到這里就創建了這個 ClassPathFileSystemWatcher 類 👇


這里我們注意到它實現了三個接口,經過前面 Spring 文章的學習,咱們知道第一步就該看啥了😄

根據類的初始化,先看看有 static 相關的代碼沒,接著看 構造器 ,最后就來到這個初始化方法 afterPropertiesSet 啦😄

這里沒有 static 方法,構造器也很簡單,就是獲取 FileSystemWatcherFactory ?,ClassPathRestartStrategy 和 監視的文件路徑,那么就看看 afterPropertiesSet 寫了什么叭 👇


ClassPathFileChangeListener

這個也不復雜,就監聽到文件改變后,發布事件 ClassPathChangedEvent


FileSystemWatcher

接著就是這個 start 方法啦👇

很明顯就是開啟一個線程,那么咱們來看看線程中到底在 run 什么🐷


找到這個任務類 Watcher 👇


可以發現它的任務就是一直 scanpollInterval 默認是 1squietPeriod 默認是 0.4s

意思是每次輪詢的時間是 1s ,包含中間休息的 0.4s ,休息事件是來確認文件在這個期間沒有再次被改動。

改動了的話會回調 FileChangeListeneronChange ,對應我們上面的這個 ClassPathFileChangeListener ,會去發布事件 ClassPathChangedEvent 😋

ApplicationListener

繞了一大圈,終于描述完了這個監視器 ClassPathFileSystemWatcher ,同時,我們也得把目光移到這個RestartConfiguration 的第二個核心 監聽器 👇

如圖所示,這個方法的作用就是重啟應用 restart


重啟應用

重啟的過程中呢,包括兩個步驟,第一步 stop ,第二步 start

stop 部分就是毀滅這些東西了,這里也藏了很多細節,有很多并發相關的知識點 😋

比如

一. ReentrantLock ?是寫在 try catch 的里面還是外面?

二. 循環里的 rootContexts 其實是 CopyOnWriteArrayList 類型的

三. 通過強制的 OOM 來清除所有的 軟/弱引用 (😱 還有這種操作的!)


start 的過程中,是通過創建這個重啟線程 RestartLauncher 來實現的,可以發現該類的任務就是找到 mainclass 并調用 main 方法,完成重啟。


而在這個過程中,就涉及到這個 classloader 啦。

ClassLoader

細心的小伙伴可以發現上面這行代碼中,調用到了這個 ClassLoader ,這個 getContextClassLoader() 是屬于 Thread 類的,通過它可以獲取到當前線程上下文的 ClassLoader

Class.forName(this.mainClassName,?false,?getContextClassLoader());

在創建這個 RestartLauncher 線程時,就已經將咱們這個 RestartClassLoader ?給傳進來了。



重啟時,就直接通過 RestartClassLoader ?去找到 main 方法,完成重啟。


很明顯這里 破壞了雙親委派機制,先從自身查找,沒有的話再去父類查找

這里 業務代碼 都被 RestartClassLoader 加載了,而每次重啟都會重新創建這個 RestartClassLoader ?,然后去加載業務代碼 🐖 (通過傳進來的 URL ?可以發現)

那么到此,這個 重啟 的過程就完成了。

差點忘了,這里還有個默認的監視范圍🐷

監視策略

如下圖👇 默認策略中,這些路徑下的文件變化不被檢測

image-20210920230435492

可通過配置修改

spring.devtools.restart.exclude=static/**,public/**

總結

通過閱讀源碼,我們知道了 spring-boot-devtools 是通過自定義 RestartClassLoader ?來加載業務代碼,并在重啟時銷毀它,再重新創建,進而重新獲取代碼,實現這個快速重啟的。

而其他 jar 包等由另外的 ClassLoader ?加載,不受影響。

同時,也可以看到 Spring 事件機制 無處不在的身影,還有各種初始化的操作,以及線程,并發,鎖在重啟過程中的使用,這些就需要小伙伴們打開源碼自身感受了,如 守護線程ReentrantLockCopyOnWriteArrayListCountDownLatch ,甚至 OOM 都能這么用!

還有 重啟 原來就是 反射調用 main 方法 呀🐷

重啟過程源碼要點



本文就分享到這里啦,喜歡的朋友點個贊再走哦

往期推薦

Spring 事務失效的 8 種場景!


實戰,實現冪等的8種方案!


絕絕子,畫框架圖就用這個工具


總結

以上是生活随笔為你收集整理的SpringBoot 热部署神器快速重启的秘密!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。