1. 程式人生 > >spring中自動註解配置以及@Resource和@Autowired的區別

spring中自動註解配置以及@Resource和@Autowired的區別

1.spring中自動註解需要配置標籤<context:component-scan>

配置完這個標籤後,spring就會去自動掃描base-package對應的路徑或者該路徑的子包下面的java檔案,如果掃描到檔案中帶有@Service,@Component,@Repository,@Controller等這些註解的類,則把這些類註冊為bean

檔案中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>那麼<context:annotation-config/>標籤就可以不用在xml中再配置了,因為前者包含了後者。
 另外<context:annotation-config/>還提供了兩個子標籤 <context:include-filter>和 <context:exclude-filter>

下面是一個比較詳細的component-scan配置:

<context:component-scan base-package="com.wjx.betalot"
<!-- 掃描的基本包路徑 -->
annotation-config="true" <!-- 是否啟用屬性注入註解 --> name-generator="org.springframework.context.annotation.AnnotationBeanNameGenerator" <!-- Bean的ID策略生成器 --> resource-pattern="**/*.class" <!-- 對資源進行篩選的正則表示式,這邊是個大的範疇,具體細分在include-filter與exclude-filter中進行 -->
scope-resolver="org.springframework.context.annotation.AnnotationScopeMetadataResolver" <!-- scope解析器 ,與scoped-proxy只能同時配置一個 --> scoped-proxy="no" <!-- scope代理,與scope-resolver只能同時配置一個 --> use-default-filters="false" <!-- 是否使用預設的過濾器,預設值true --> > <!-- 注意:若使用include-filter去定製掃描內容,要在use-default-filters="false"的情況下,不然會“失效”,被預設的過濾機制所覆蓋 --> <!-- annotation是對註解進行掃描 --> <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/> <!-- assignable是對類或介面進行掃描 --> <context:include-filter type="assignable" expression="com.wjx.betalot.performer.Performer"/> <context:include-filter type="assignable" expression="com.wjx.betalot.performer.impl.Sonnet"/> <!-- 注意:在use-default-filters="false"的情況下,exclude-filter是針對include-filter裡的內容進行排除 --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="assignable" expression="com.wjx.betalot.performer.impl.RainPoem"/> <context:exclude-filter type="regex" expression=".service.*"/> </context:component-scan>

這裡寫圖片描述

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,所以這一點在實際使用中還是需要注意一下的。

2 @Resource和@Autowired 的區別

@Resource的作用相當於@Autowired,只不過@Autowired按byType自動注入,而@Resource預設按 byName自動注入罷了。@Resource有兩個屬性是比較重要的,分是name和type,Spring將@Resource註解的name屬性解析為bean的名字,而type屬性則解析為bean的型別。所以如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。如果既不指定name也不指定type屬性,這時將通過反射機制使用byName自動注入策略。
  @Resource裝配順序
  1. 如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則丟擲異常
  2. 如果指定了name,則從上下文中查詢名稱(id)匹配的bean進行裝配,找不到則丟擲異常
  3. 如果指定了type,則從上下文中找到型別匹配的唯一bean進行裝配,找不到或者找到多個,都會丟擲異常
  4. 如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始型別進行匹配,如果匹配則自動裝配;

@Autowired 與@Resource的區別:

1、 @Autowired與@Resource都可以用來裝配bean. 都可以寫在欄位上,或寫在setter方法上。

2、 @Autowired預設按型別裝配(這個註解是屬業spring的),預設情況下必須要求依賴物件必須存在,如果要允許null值,可以設定它的required屬性為false,如:@Autowired(required=false) ,如果我們想使用名稱裝配可以結合@Qualifier註解進行使用,如下:

@Autowired()
@Qualifier(“baseDao”)
private
BaseDao baseDao;

3、@Resource(這個註解屬於J2EE的),預設安裝名稱進行裝配,名稱可以通過name屬性進行指定,如果沒有指定name屬性,當註解寫在欄位上時,預設取欄位名進行安裝名稱查詢,如果註解寫在setter方法上預設取屬性名進行裝配。當找不到與名稱匹配的bean時才按照型別進行裝配。但是需要注意的是,如果name屬性一旦指定,就只會按照名稱進行裝配。

@Resource(name=”baseDao”)
private
BaseDao baseDao;