Spring -- 使用說明


  在xml配置了這個標簽后,spring可以自動去掃描base-pack下面或者子包下面的java文件,如果掃描到有@Component @Controller@Service等這些注解的類,則把這些類注冊為bean

注意:如果配置了<context:component-scan>那么<context:annotation-config/>標簽就可以不用再xml中配置了,因為前者包含了后者。另外<context:component-scan>還提供了兩個子標簽

  <context:include-filter> 和 <context:exclude-filter>,注意,兩個標簽不能同時使用,然會報錯

<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>

  錯誤信息:"發現了以元素 'context:include-filter' 開頭的無效內容。應以 '{"http://www.springframework.org/schema/context":exclude-filter}' 之一開頭。"

filter標簽的type和表達式說明如下:

 Filter Type Examples Expression Description
annotation org.example.SomeAnnotation 符合SomeAnnoation的target class
assignable org.example.SomeClass 指定class或interface的全名
aspectj org.example..*Service+ AspectJ語法
regex org\.example\.Default.* Regelar Expression
custom org.example.MyTypeFilter Spring3新增自訂Type,實作org.springframework.core.type.TypeFilter

 

<context:include-filter type="regex" expression="com\.only\.mate\.[^.]+(Controller|Service)"/>

  在我們的示例中,將filter的type設置成了正則表達式,regex,注意在正則里面.表示所有字符,而\.才表示真正的.字符。

 

  在說明這兩個子標簽前,先說一下<context:component-scan>有兩個屬性,base-package屬性告訴spring要掃描的包,use-default-filters="true"(默認為true)表示使用默認的過濾器,此處的默認過濾器,會掃描指定包下的全部的標有@Component的類以及@Component的子注解@Service,@Repository,@Controller等的類,並注冊成bean。所以如果僅僅是在配置文件中這么寫

<context:component-scan base-package="com.only.mate"/>

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

 

 可以發現這種掃描的粒度有點太大,如果你只想掃描指定包下面的Controller,該怎么辦?。如下所示

第一種:base-package指定到Controller類的包名下

<context:component-scan base-package="com.only.mate.controller" /> 

 這樣掃描base-package(這個包下只有Controller注釋的類)下的類,並注冊成bean。

第二種:如下所示

(推薦這樣的方式)
<
context:component-scan base-package="com.only.mate" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>

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

或則

<context:component-scan base-package="com.only.mate" use-default-filters="true">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>

這樣就會只掃描base-package指定下的除了@Service下的java類,並注冊成bean。

 

特別要注意的是:

如果將第二種方法的use-dafault-filter改為相反的值,就會產生與你期望相悖的結果

如下所示:

<context:component-scan base-package="com.only.mate" use-default-filters="true">  
    <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配置多個包名這種不是很優雅的方法來解決這個問題了。

 

<context:component-scan base-package="com.only.mate" use-default-filters="false"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" /> </context:component-scan>

“No mapping found for HTTP request with URI [/SpringMVC/user/index] in DispatcherServlet with name 'springServlet'”,沒有掃描Controller注解。

 


 

為什么會出現這樣的結果呢?

  關鍵在於use-default-filters的值決定掃描的注解類型,這里又要提到這個屬性的作用了。

  use-default-filters="true"(默認為true)表示使用默認的過濾器,此處的默認過濾器,會掃描指定包下的全部的標有@Component的類以及@Component的子注解@Service,@Repository,@Controller等的類,並注冊成bean。

具體分析如下:

 

<context:component-scan base-package="com.only.mate" use-default-filters="true"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>

 

這種情況use-default-filters="true",默認會掃描包含Service,Component,Repository,Controller注解修飾的類,我們加上了<context:include-filter>標簽后,也只是說增加掃描類型,再原有的基礎上在增加,所以這樣會掃描包含Service,Component,Repository,Controller注解修飾的類以及自己新增的類型的類。(注意:這里會重復掃描Service注解,從而導致事務失效

 

 

<context:component-scan base-package="com.only.mate" use-default-filters="false"> 
  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>

 

這種情況use-default-filters="false",所以不會掃描任何類,我們加上了<context:exclude-filter>標簽后,也只是說過濾掃描類型,再原有的基礎上在減少,所以這樣依然沒有掃描任何類,所以當啟動項目訪問的時候會出現“No mapping found for HTTP request with URI [/SpringMVC/user/index] in DispatcherServlet with name 'springServlet'”,說明沒有掃描Controller注解。

 

 

綜上所述:

  首先要考慮Use-dafault-filters值的設置,然后在考慮使用<context:exclude-filter>指定不掃描和<context:include-filter>指定掃描

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM