Spring -- 使用說明

  在xml配置了這個標籤後,spring能夠自動去掃描base-pack下面或者子包下面的java文件,若是掃描到有@Component @Controller@Service等這些註解的類,則把這些類註冊爲beanjava

注意:若是配置了<context:component-scan>那麼<context:annotation-config/>標籤就能夠不用再xml中配置了,由於前者包含了後者。另外<context:component-scan>還提供了兩個子標籤正則表達式

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

<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}' 之一開頭。"express

filter標籤的type和表達式說明以下:app

 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,注意在正則裏面.表示全部字符,而\.才表示真正的.字符。spa

 

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

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

 Use-default-filter此時爲true那麼會對base-package包或者子包下的全部的進行java類進行掃描,並把匹配的java類註冊成bean。component

 

 能夠發現這種掃描的粒度有點太大,若是你只想掃描指定包下面的Controller,該怎麼辦?。以下所示xml

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

<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>指定掃描

相關文章
相關標籤/搜索