tomcat部署war包步驟「tomcat啟動war包原理」

Springboot工程war包模式啟動流程

Springboot工程war包模式啟動流程

出於項目部署的需要,目前做的一個項目需要通過war包進行部署,那麼就帶來一個問題,就是在原本的main方法中進行的一些邏輯會失效,以至於出現一些不可預知的錯誤#1。在這裡載入了一個classpath下的一個json文件,將其載入到系統屬性中,但是在後續運行時出現NullPointException。很納悶,我這本地運行的好好的,咋發布到環境上就出問題了,後面一翻源碼才明白,原來我們本地運行是java -jar模式運行的,此時虛擬機運行的是工程的main方法。但是發布到環境後,是以war包運行的,此時將不會執行本工程的main方法,而是由tomcat的main方法進行啟動。這個時候問題問題就來了,數據沒載入到全局系統變數中。
1#

Springboot工程war包模式啟動流程

在查閱了spring-web這個依賴後,在META-INF下有services的文件夾,
javax.servlet.ServletContainerInitializer,這個東西具體是幹什麼的呢?其實就是在tomcat啟動後,通過JDK的SPI調用實現了文件裡面的類,這裡spring使用了org.springframework.web.SpringServletContainerInitializer,打開這個類會發現class上有個HandlesTypes的註解,那麼這個裡面修飾的class是做什麼用的呢,主要作為onStartup方法的入參使用——webAppInitializerClasses
會收集所有實現了這個介面的類,循環調用他們的onStartup方法。
#2

Springboot工程war包模式啟動流程

#3

Springboot工程war包模式啟動流程

然後我們的啟動類
org.springframework.boot.web.servlet.support.SpringBootServletInitializer剛好又是它的子類,那麼會調用到它。這裡採用了模板設計模式。

org.springframework.boot.web.servlet.support.SpringBootServletInitializer#configure這個方法作為org.springframework.boot.web.servlet.support.SpringBootServletInitializer#createRootApplicationContext的一部分,作為鉤子方法影響主流程。構建出一個SpringApplication對象後執行它的run方法,這裡就是最常規的Springboot工程啟動了

#4

Springboot工程war包模式啟動流程

最後的解決方案是通過訂閱spring的容器刷新事件來完成靜態數據的載入#5,因為無論是jar包啟動,還是war包啟動,都是要調用spring的核心方法——refresh,當刷新完成後,會拋出一個ContextRefreshedEvent事件,所有訂閱這個事件的bean都會收到,在這裡進行部分操作完成一些數據載入工作
#5

Springboot工程war包模式啟動流程

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/208916.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-08 15:22
下一篇 2024-12-08 15:22

相關推薦

發表回復

登錄後才能評論