Spring 2.5 中除了提供 @Component 註釋外,還定義了幾個擁有特殊語義的註釋,它們分別是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,這 3 個註釋和 @Component 是等效的,可是從註釋類的命名上,很容易看出這 3 個註釋分別和持久層、業務層和控制層(Web 層)相對應。雖然目前這 3 個註釋和 @Component 相比沒有什麼新意,但 Spring 將在之後的版本中爲它們添加特殊的功能。因此,若是 Web 應用程序採用了經典的三層分層結構的話,最好在持久層、業務層和控制層分別採用 @Repository、@Service 和 @Controller 對分層中的類進行註釋,而用 @Component 對那些比較中立的類進行註釋。
在一個稍大的項目中,一般會有上百個組件,若是這些組件採用xml的bean定義來配置,顯然會增長配置文件的體積,查找以及維護起來也不太方便。 Spring2.5爲咱們引入了組件自動掃描機制,他能夠在類路徑底下尋找標註了 @Component,@Service,@Controller,@Repository註解的類,並把這些類歸入進spring容器中管理。它的做用和在xml文件中使用bean節點配置組件時同樣的。要使用自動掃描機制,在 spring的配置文件裏面只須要加上<context:annotation-config/> 和<context:component-scan base-package="須要實現注入的類所在包"/>,可使用base-package="*"表示所有的類。 配置自動掃描以下:java
<?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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" > <context:component-scan base-package=」com.eric.spring」> </beans>
其中base-package爲須要掃描的包(含全部子包),各個註解的理解以下:
@Service
public class VentorServiceImpl implements iVentorService { } @Repository
public class VentorDaoImpl implements iVentorDao { }
getBean的默認名稱是類名(頭字母小寫),若是想自定義,能夠@Service(「aaaaa」)這樣來指定,這種bean默認是單例的,若是想改變,可使用@Service(「beanName」) @Scope(「prototype」)來改變。可使用如下方式指定初始化方法和銷燬方法(方法名任意):
@PostConstruct public void init() { } @PreDestroy public void destory() { }
spring2.5提供了基於註解(Annotation-based)的配置,咱們能夠經過註解的方式來完成注入依賴。bean注入可使用@Autowired、@Resource來完成。但它們之間是有區別的。首先來看一下:spring
a、@Resource默認是按照名稱來裝配注入的,只有當找不到與名稱匹配的bean纔會按照類型來裝配注入;sql
b、@Autowired默認是按照類型裝配注入的,若是想按照名稱來轉配注入,則須要結合@Qualifier一塊兒使用;當候選 Bean 數目不爲1時的應對方法,在默認狀況下使用 @Autowired 註釋進行自動注入時,Spring 容器中匹配的候選 Bean 數目必須有且僅有一個。當找不到一個匹配的 Bean 時,Spring 容器將拋出 BeanCreationException 異常,並指出必須至少擁有一個匹配的 Bean。固然,通常狀況下,使用 @Autowired 的地方都是須要注入 Bean 的,使用了自動注入而又容許不注入的狀況通常僅會在開發期或測試期碰到(如爲了快速啓動 Spring 容器,僅引入一些模塊的 Spring 配置文件),因此 @Autowired(required = false) 會不多用到。測試
c、@Resource註解是由J2EE提供,而@Autowired是由Spring提供,故減小系統對spring的依賴建議使用@Resource的方式;ui
d、@Resource和@Autowired均可以書寫標註在字段或者該字段的setter方法之上this
e、使用@Autowired時你的Bean必須以@Service或@Component註解才行編碼
註解與傳統的編碼方式實現的注入的不一樣用法須要注意下:例子,把DAO實現類注入到service實現類中,把service的接口(注意不要是service的實現類)注入到action中,注入時不要new這個注入的類,由於spring會自動注入,若是手動再new的話會出現錯誤,而後屬性加上@Autowired後不須要getter()和setter()方法,Spring也會自動注入。
spa
(1)@Resource示例:prototype
public class StudentService3 implements IStudentService { //@Resource(name="studentDao")放在此處也是可行的 private IStudentDao studentDao; private String id; public void setId(String id) { this.id = id; } @Resource(name="studentDao") // 經過此註解完成從spring配置文件中查找名稱爲studentDao的bean來裝配字段studentDao,若是spring配置文件中不存在 studentDao名稱的bean則轉向按照bean類型經行查找 public void setStudentDao(IStudentDao studentDao) { this.studentDao = studentDao; } public void saveStudent() { studentDao.saveStudent(); System.out.print(",ID 爲:"+id); } }
配置文件添加以下信息code
<bean id="studentDao" class="com.wch.dao.impl.StudentDao"></bean> <bean id="studentService3" class="com.wch.service.impl.StudentService3" />
@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方式進行裝配;若是沒有匹配,則回退爲一個原始類型進行匹配,若是匹配則自動裝配;
(2)@Autowired示例1
public class StudentService3 implements IStudentService { //@Autowired放在此處也是可行的 private IStudentDao studentDao; private String id; public void setId(String id) { this.id = id; } @Autowired//經過此註解完成從spring配置文件中 查找知足studentDao類型的bean //@Qualifier("studentDao")則按照名稱經行來查找轉配的 public void setStudentDao(IStudentDao studentDao) { this.studentDao = studentDao; } public void saveStudent() { studentDao.saveStudent(); System.out.print(",ID 爲:"+id); } }
配置文件添加以下信息
<bean id="studentDao" class="com.wch.dao.impl.StudentDao"></bean> <bean id="studentService3" class="com.wch.service.impl.StudentService3" />
三、@Autowired示例2
@Service("OrganDaoIbatis ") public class OrganDaoIbatis extends BaseDao implements IOrganDao { @Autowired(required=false) @Qualifier("sqlMapClient") private SqlMapClient sqlClient = null;
使用 @Autowired(required = false)做用:
在默認狀況下使用 @Autowired
註釋進行自動注入時,Spring 容器中匹配的候選 Bean 數目必須有且僅有一個。當找不到一個匹配的 Bean 時,Spring 容器將拋出 BeanCreationException
異常,並指出必須至少擁有一個匹配的 Bean。
固然,通常狀況下,使用 @Autowired
的地方都是須要注入 Bean 的,使用了自動注入而又容許不注入的狀況通常僅會在開發期或測試期碰到(如爲了快速啓動 Spring 容器,僅引入一些模塊的 Spring 配置文件),因此 @Autowired(required = false)
會不多用到。
@Qualifier 註釋指定注入 Bean 的名稱 做用:
和找不到一個類型匹配 Bean 相反的一個錯誤是:若是 Spring 容器中擁有多個候選 Bean,Spring 容器在啓動時也會拋出BeanCreationException
異常。
使用Autowired時你的OrganDaoIbatis 必須以@Service或@Component註解才行。
在接口前面標上@Autowired和@Qualifier註釋使得接口能夠被容器注入,當接口存在兩個實現類的時候必須指定其中一個來注入,使用實現類首字母小寫的字符串來注入,如:
@Autowired @Qualifier("chinese") private Man man;
不然能夠省略,只寫@Autowired。
總結:在java代碼中可使用@Autowire或者@Resource註解方式進行裝配,這兩個註解的區別是:
@Autowire 默認按照類型裝配,默認狀況下它要求依賴對象必須存在若是容許爲null,能夠設置它required屬性爲false,若是咱們想使用按照名稱裝配,可 以結合@Qualifier註解一塊兒使用;
@Resource默認按照名稱裝配,當找不到與名稱匹配的bean纔會按照類型裝配,能夠經過name屬性指定,若是沒有指定name屬 性,當註解標註在字段上,即默認取字段的名稱做爲bean名稱尋找依賴對象,當註解標註在屬性的setter方法上,即默認取屬性名做爲bean名稱尋找 依賴對象.
注意:若是沒有指定name屬性,而且按照默認的名稱仍然找不到依賴的對象時候,會回退到按照類型裝配,但一旦指定了name屬性,就只能按照名稱 裝配了。
Spring 配置文件中 dependency-check 依賴檢查的靈活性不夠,並不能知足咱們全部的需求
Spring還提供一種更加靈活的檢查方式
@Required註解檢查 但他只檢查屬性是否已經設置而不會測試屬性是否非空
下面咱們看一下如何使用Spring提供的此機制
首先咱們須要在程序裏面加上註解
@Required public void setProduct(Product product) { this.product = product; }
注意@Required只能設置在setter方法上
接着咱們須要在 配置文件中加上這樣一句話
<bean class="org.springframework.beans.factory.annotation.
RequiredAnnotationBeanPostProcessor"/>
這是Spring的一個處理器用於檢查
若是Spring的版本是2.5或以上,咱們能夠直接用下列方式來配置
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/>
這是簡寫形式
這樣就配置完成了,這樣若是任何帶有@Required的屬性未設置的話 將會拋出BeanInitializationException異常