Spring的同一個(gè)服務(wù)會(huì)加載多次的問(wèn)題分析及解決方法
問(wèn)題現(xiàn)象
最近在本地調(diào)試公司的一個(gè)Web項(xiàng)目時(shí),無(wú)意中發(fā)現(xiàn)日志中出現(xiàn)了兩次同一個(gè)服務(wù)的init記錄,項(xiàng)目都是基于Spring來(lái)搭建的,按理說(shuō)服務(wù)都是單例的,應(yīng)該只有一次服務(wù)加載日志才對(duì),本著對(duì)工作認(rèn)真負(fù)責(zé)(閑來(lái)無(wú)事)的態(tài)度,必然要一探究竟。
問(wèn)題分析
為什么同一個(gè) Bean 會(huì)被容器初始化兩次?
首先,我們先來(lái)梳理一下 Web 容器中如何加載 Bean:
在 Web 容器中,ContextLoaderListener
和 DispatchServlet
都會(huì)在容器啟動(dòng)的時(shí)候加載
Bean,區(qū)別在于 DispatchServlet
一般會(huì)加載 MVC 相關(guān)的 Bean,ContextLoaderListener
會(huì)加載 Spring 相關(guān)的 Bean,二者會(huì)分別生成一個(gè)WebApplicationContext
。
根據(jù) web.xml 的加載順序,listener 會(huì)先于 Servlet 加載,當(dāng)獲取 Bean 時(shí),會(huì)優(yōu)先從DispatchServlet
生成的 WebApplicationContext
中查找,如果找不到再?gòu)腃ontextLoaderListener
生成的 WebApplicationContext
中查找。
那么如果這兩個(gè)加載了同樣的Bean,到底該用誰(shuí)的呢?
如果二者的配置文件中定義了相同的 Bean,則實(shí)際使用中只會(huì)用到 DispatchServlet
中的
Bean,ContextLoaderListener
中的 Bean 無(wú)法調(diào)用,造成內(nèi)存泄漏。
接下來(lái)我們看一下項(xiàng)目中的 web.xml 配置,如下圖所示,ContextLoaderListener
和DispatchServlet
加載了相同的配置 spring.xml,所以會(huì)出現(xiàn)兩次 Bean 的初始化現(xiàn)象。
解決方案
經(jīng)過(guò)上面的分析,我們知道了,之所以同一個(gè)Bean會(huì)被加載兩次,是由于我們?cè)?code>DispatchServlet和ContextLoaderListener
都定義了這個(gè)Bean。
因此,我們要做的就是讓ContextLoaderListener
和DispatcherServlet
分別加載不同的Bean:
新增applicationContext.xml,其中聲明ContextLoaderListener要加載的Bean:
修改spring.xml中的包掃描范圍,讓DispatcherServlet只加載mvc相關(guān)的Bean:
啟動(dòng)服務(wù),查看初始化信息,Service只被初始化了一次:
到此這篇關(guān)于Spring的同一個(gè)服務(wù)為什么會(huì)加載多次?的文章就介紹到這了,更多相關(guān)Spring的同一個(gè)服務(wù)為什么會(huì)加載多次??jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java:程序包org.bouncycastle.jce.provider不存在問(wèn)題及解決
這篇文章主要介紹了java:程序包org.bouncycastle.jce.provider不存在問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05SpringBoot項(xiàng)目中java -jar xxx.jar沒(méi)有主清單屬性的解決方法
這篇文章主要給大家介紹了SpringBoot項(xiàng)目中java -jar xxx.jar沒(méi)有主清單的解決方法,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-01-01Spring自動(dòng)裝配Bean實(shí)現(xiàn)過(guò)程詳解
這篇文章主要介紹了Spring自動(dòng)裝配Bean實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02Spring Boot+Nginx實(shí)現(xiàn)大文件下載功能
相信很多小伙伴,在日常開(kāi)放中都會(huì)遇到大文件下載的情況,大文件下載方式也有很多,比如非常流行的分片下載、斷點(diǎn)下載;當(dāng)然也可以結(jié)合Nginx來(lái)實(shí)現(xiàn)大文件下載,在中小項(xiàng)目非常適合使用,這篇文章主要介紹了Spring Boot結(jié)合Nginx實(shí)現(xiàn)大文件下載,需要的朋友可以參考下2024-05-05java web服務(wù)器實(shí)現(xiàn)跨域訪問(wèn)
這篇文章主要為大家詳細(xì)介紹了java web服務(wù)器實(shí)現(xiàn)跨域訪問(wèn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08SpringBoot使用CXF集成WebService的方法
這篇文章主要介紹了SpringBoot使用CXF集成WebService的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08SpringBoot深入分析講解監(jiān)聽(tīng)器模式上
監(jiān)聽(tīng)器模式,大家應(yīng)該并不陌生,主要的組成要素包括了事件、監(jiān)聽(tīng)器以及廣播器;當(dāng)事件發(fā)生時(shí),廣播器負(fù)責(zé)將事件傳遞給所有已知的監(jiān)聽(tīng)器,而監(jiān)聽(tīng)器會(huì)對(duì)自己感興趣的事件進(jìn)行處理2022-07-07java復(fù)制文件和java移動(dòng)文件的示例分享
本文主要介紹了java將文件夾下面的所有的jar文件拷貝到指定的文件夾下面的方法,需要的朋友可以參考下2014-02-02