1. 程式人生 > >context:component-scan 的使用說明

context:component-scan 的使用說明

轉載地址:https://blog.csdn.net/qwe5810658/article/details/74343228

通常情況下我們在建立spring專案的時候在xml配置檔案中都會配置這個標籤,配置完這個標籤後,spring就會去自動掃描base-package對應的路徑或者該路徑的子包下面的java檔案,如果掃描到檔案中帶有@Service,@Component,@Repository,@Controller等這些註解的類,則把這些類註冊為bean 
注:在註解後加上例如@Component(value=”abc”)時,註冊的這個類的bean的id就是adc.

注:如果配置了<
context:component-scan>, 那麼<context:annotation-config/>標籤就可以不用在xml中再配置了, 因為前者包含了後者。另外<context:annotation-config/>還提供了兩個子標籤 <context:include-filter><context:exclude-filter>
 

在註解注入之前也必須在spring的配置檔案中做如下配置,我們看下spring.xml檔案的內容:

xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"
> <context:component-scan base-package="com.sparta.trans" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> </beans>

這個配置檔案中必須宣告xmlns:context 這個xml名稱空間,在schemaLocation中需要指定schema:

http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd

 

這個檔案中beans根節點下只有一個context:component-scan節點,此節點有兩個屬性base-package屬性告訴spring要掃描的包,use-default-filters=”false”表示不要使用預設的過濾器,此處的預設過濾器,會掃描包含@Service,@Component,@Repository,@Controller註解修飾的類,use-default-filters屬性的預設值為true,這就意味著會掃描指定包下標有@Service,@Component,@Repository,@Controller的註解的全部類,並註冊成bean。 
所以如果僅僅是在配置檔案中寫<context:component-scan base-package="com.sparta.trans"/> Use-default-filter此時為true時,那麼會對base-package包或者子包下所有的java類進行掃描,並把匹配的java類註冊成bean。

所以這用情況下可以發現掃描的力度還是挺大的,但是如果你只想掃描指定包下面的Controller,那該怎麼辦?此時子標籤<context:incluce-filter>就可以發揮作用了。如下所示

context:component-scan base-package="com.sparta.trans.controller">

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

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

</context:component-scan> 

 

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

注: context:component-scan節點允許有兩個子節點和。filter標籤的type和表示式說明如下:

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

在我們的示例中,將filter的type設定成了正則表示式,regex,注意在正則裡面.表示所有字元,而.才表示真正的.字元。我們的正則表示以Controller或者Service結束的類。 
我們也可以使用annotaion來限定,如上面註釋掉的所示。這裡我們指定的include-filter的type是annotation,expression則是註解類的全名。

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

<context:component-scan base-package="com.sparta.trans">  

<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指定的包中有的子包是不含有註解的,所以不用掃描,此時可以指定來進行過濾,說明此包不需要被掃描。所以綜上可以看出 use-dafault-filters=”false”的情況下:可以指定不需要掃描的路徑來排除掃描這些檔案,可以指定需要掃描的路徑來進行掃描。但是由於use-dafault-filters的值預設為true,所以這一點在實際使用中還是需要注意一下的。


@Service告訴spring容器,這是一個Service類,標識持久層Bean元件,預設情況會自動載入它到spring容器中。 
@Autowried註解告訴spring,這個欄位需要自動注入 
@Scope指定此spring bean的scope是單例 
@Repository註解指定此類是一個容器類,是DA層類的實現。標識持久層Bean元件 
@Componet:基本註解,標識一個受Spring管理的Bean元件 
@Controller:標識表現層Bean元件

context.component-scan節點

base-package屬性告訴spring要掃描的包 
use-default-filters=”false”表示不要使用預設的過濾器,此處的預設過濾器,會掃描包含Service,Component,Responsitory,Controller註釋修飾類。