首頁 > 軟體

關於SpingMVC的<context:component-scan>包掃描踩坑記錄

2022-03-21 13:02:50

<context:component-scan>包掃描的坑

公司專案設定的Spring專案的包掃描有點問題,出現了一個被Spring容器管理的Bean被建立了2次的現象。在此記錄下解決的過程,方便後續查閱。

改動前

容器啟動監聽器中會掃描全部包,建立範例 

SpringMVC組態檔也會掃描全部包,建立範例

產生的問題:加了註解的類的範例都建立了2個

改動後

容器啟動監聽器裡面負責非Controller層bean的建立

SpingMVC組態檔裡只負責Controller層bean的建立

<context:component-scan>的使用說明

在xml設定了這個標籤後,spring可以自動去掃描base-package下面或者子包下面的java檔案,如果掃描到有@Component @Controller@Service等這些註解的類,則把這些類註冊為bean

注意:如果設定了<context:component-scan>那麼<context:annotation-config/>標籤就可以不用再xml中設定了,因為前者包含了後者。

<context:annotation-config/>提供了兩個子標籤

<context:include-filter>
<context:exclude-filter>

再說明這兩個子標籤前,先說一下<context:component-scan>有一個use-default-filters屬性,改屬性預設為true,這就意味著會掃描指定包下的全部的標有@Component的類,並註冊成bean.也就是@Component的子註解@Service,@Reposity等。所以如果僅僅是在組態檔中這麼寫

<context:component-scan base-package="tv.huan.weisp.web"/>

use-default-filter此時為true那麼會對base-package包或者子包下的所有的進行java類進行掃描,並把匹配的java類註冊成bean。

可以發現這種掃描的粒度有點太大,如果你只想掃描指定包下面的Controller,該怎麼辦?此時子標籤context:incluce-filter就起到了用武之地。

如下所示

<context:component-scan base-package="tv.huan.weisp.web .controller">  
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>   
</context:component-scan>  

這樣就會只掃描base-package指定下的有@Controller下的java類,並註冊成bean

但是因為use-dafault-filter在上面並沒有指定,預設就為true,所以當把上面的設定改成如下所示的時候,就會產生與你期望相悖的結果(注意base-package包值得變化)

<context:component-scan base-package="tv.huan.weisp.web ">  
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>   
</context:component-scan>  

此時,spring不僅掃描了@Controller,還掃描了指定包所在的子包service包下註解@Service的java類

此時指定的include-filter沒有起到作用,只要把use-default-filter設定成false就可以了。這樣就可以避免在base-packeage設定多個包名這種不是很優雅的方法來解決這個問題了。

另外在我參與的專案中可以發現在base-package指定的包中有的子包是不含有註解了,所以不用掃描,此時可以指定<context:exclude-filter>來進行過濾,說明此包不需要被掃描。綜合以上說明

use-dafault-filters=”false”的情況下:

<context:exclude-filter>指定的不掃描,<context:include-filter>指定的掃描

定位問題原因* 根據原因思考問題解決方案* 實踐驗證方案有效性* 提交驗證結果

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com