日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring使用注释

發(fā)布時(shí)間:2024/4/17 javascript 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring使用注释 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://www.ibm.com/developerworks/cn/java/j-lo-spring25-ioc/

使用 Spring 2.5 注釋驅(qū)動(dòng)的 IoC 功能

陳 雄華 (quickselect@163.com), 技術(shù)總監(jiān), 寶寶淘網(wǎng)絡(luò)科技有限公司 陳雄華,2002 年畢業(yè)于廈門大學(xué)計(jì)算機(jī)與信息工程學(xué)院,獲碩士學(xué)位。是寶寶淘科技有限公司的創(chuàng)始人之一(http://www.baobaotao.com),這是一個(gè)服務(wù)于全國母嬰用戶的綜合性網(wǎng)站,作者負(fù)責(zé)網(wǎng)站整體框架設(shè)計(jì)以及核心代碼開發(fā)的工作。技術(shù)開發(fā)之余,常將經(jīng)驗(yàn)所得行諸于文字,作者是國內(nèi)多個(gè)著名技術(shù)網(wǎng)站的專欄作者,在各大技術(shù)網(wǎng)站、報(bào)刊雜志發(fā)表過數(shù)十篇技術(shù)文章,廣受讀者好評(píng)。于 2005 年出版《精通 JBuilder 2005》,于2007年出版《精通 Spring 2.x--企業(yè)應(yīng)用開發(fā)詳解》,其新作《EXT 2.x開發(fā)詳解――AJAX和Web頁面布局王者至尊》即將出版。

簡介:?基于注釋(Annotation)的配置有越來越流行的趨勢,Spring 2.5 順應(yīng)這種趨勢,提供了完全基于注釋配置 Bean、裝配 Bean 的功能,您可以使用基于注釋的 Spring IoC 替換原來基于 XML 的配置。本文通過實(shí)例詳細(xì)講述了 Spring 2.5 基于注釋 IoC 功能的使用。

平均分 (85個(gè)評(píng)分)
為本文評(píng)分

概述

注釋配置相對(duì)于 XML 配置具有很多的優(yōu)勢:

  • 它可以充分利用 Java 的反射機(jī)制獲取類結(jié)構(gòu)信息,這些信息可以有效減少配置的工作。如使用 JPA 注釋配置 ORM 映射時(shí),我們就不需要指定 PO 的屬性名、類型等信息,如果關(guān)系表字段和 PO 屬性名、類型都一致,您甚至無需編寫任務(wù)屬性映射信息——因?yàn)檫@些信息都可以通過 Java 反射機(jī)制獲取。
  • 注釋和 Java 代碼位于一個(gè)文件中,而 XML 配置采用獨(dú)立的配置文件,大多數(shù)配置信息在程序開發(fā)完成后都不會(huì)調(diào)整,如果配置信息和 Java 代碼放在一起,有助于增強(qiáng)程序的內(nèi)聚性。而采用獨(dú)立的 XML 配置文件,程序員在編寫一個(gè)功能時(shí),往往需要在程序文件和配置文件中不停切換,這種思維上的不連貫會(huì)降低開發(fā)效率。

因此在很多情況下,注釋配置比 XML 配置更受歡迎,注釋配置有進(jìn)一步流行的趨勢。Spring 2.5 的一大增強(qiáng)就是引入了很多注釋類,現(xiàn)在您已經(jīng)可以使用注釋配置完成大部分 XML 配置的功能。在這篇文章里,我們將向您講述使用注釋進(jìn)行 Bean 定義和依賴注入的內(nèi)容。


原來我們是怎么做的

在使用注釋配置之前,先來回顧一下傳統(tǒng)上是如何配置 Bean 并完成 Bean 之間依賴關(guān)系的建立。下面是 3 個(gè)類,它們分別是 Office、Car 和 Boss,這 3 個(gè)類需要在 Spring 容器中配置為 Bean:

Office 僅有一個(gè)屬性:


清單 1. Office.java
package com.baobaotao; public class Office {private String officeNo =”001”;//省略 get/setter@Overridepublic String toString() {return "officeNo:" + officeNo;} }

Car 擁有兩個(gè)屬性:


清單 2. Car.java
package com.baobaotao;public class Car {private String brand;private double price;// 省略 get/setter@Overridepublic String toString() {return "brand:" + brand + "," + "price:" + price;} }

Boss 擁有 Office 和 Car 類型的兩個(gè)屬性:


清單 3. Boss.java
package com.baobaotao;public class Boss {private Car car;private Office office;// 省略 get/setter@Overridepublic String toString() {return "car:" + car + "\n" + "office:" + office;} }

我們?cè)?Spring 容器中將 Office 和 Car 聲明為 Bean,并注入到 Boss Bean 中:下面是使用傳統(tǒng) XML 完成這個(gè)工作的配置文件 beans.xml:


清單 4. beans.xml 將以上三個(gè)類配置成 Bean
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"><bean id="boss" class="com.baobaotao.Boss"><property name="car" ref="car"/><property name="office" ref="office" /></bean><bean id="office" class="com.baobaotao.Office"><property name="officeNo" value="002"/></bean><bean id="car" class="com.baobaotao.Car" scope="singleton"><property name="brand" value=" 紅旗 CA72"/><property name="price" value="2000"/></bean> </beans>

當(dāng)我們運(yùn)行以下代碼時(shí),控制臺(tái)將正確打出 boss 的信息:


清單 5. 測試類:AnnoIoCTest.java
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AnnoIoCTest {public static void main(String[] args) {String[] locations = {"beans.xml"};ApplicationContext ctx = new ClassPathXmlApplicationContext(locations);Boss boss = (Boss) ctx.getBean("boss");System.out.println(boss);} }

這說明 Spring 容器已經(jīng)正確完成了 Bean 創(chuàng)建和裝配的工作。


使用 @Autowired 注釋

Spring 2.5 引入了 @Autowired 注釋,它可以對(duì)類成員變量、方法及構(gòu)造函數(shù)進(jìn)行標(biāo)注,完成自動(dòng)裝配的工作。來看一下使用@Autowired 進(jìn)行成員變量自動(dòng)注入的代碼:


清單 6. 使用 @Autowired 注釋的 Boss.java
package com.baobaotao; import org.springframework.beans.factory.annotation.Autowired;public class Boss {@Autowiredprivate Car car;@Autowiredprivate Office office;… }

Spring 通過一個(gè) BeanPostProcessor 對(duì)@Autowired 進(jìn)行解析,所以要讓 @Autowired 起作用必須事先在 Spring 容器中聲明AutowiredAnnotationBeanPostProcessor Bean。


清單 7. 讓 @Autowired 注釋工作起來
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"><!-- 該 BeanPostProcessor 將自動(dòng)起作用,對(duì)標(biāo)注 @Autowired 的 Bean 進(jìn)行自動(dòng)注入 --><bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/><!-- 移除 boss Bean 的屬性注入配置的信息 --><bean id="boss" class="com.baobaotao.Boss"/><bean id="office" class="com.baobaotao.Office"><property name="officeNo" value="001"/></bean><bean id="car" class="com.baobaotao.Car" scope="singleton"><property name="brand" value=" 紅旗 CA72"/><property name="price" value="2000"/></bean> </beans>

這樣,當(dāng) Spring 容器啟動(dòng)時(shí),AutowiredAnnotationBeanPostProcessor 將掃描 Spring 容器中所有 Bean,當(dāng)發(fā)現(xiàn) Bean 中擁有@Autowired 注釋時(shí)就找到和其匹配(默認(rèn)按類型匹配)的 Bean,并注入到對(duì)應(yīng)的地方中去。

按照上面的配置,Spring 將直接采用 Java 反射機(jī)制對(duì) Boss 中的 caroffice 這兩個(gè)私有成員變量進(jìn)行自動(dòng)注入。所以對(duì)成員變量使用@Autowired 后,您大可將它們的 setter 方法(setCar()setOffice())從 Boss 中刪除。

當(dāng)然,您也可以通過 @Autowired 對(duì)方法或構(gòu)造函數(shù)進(jìn)行標(biāo)注,來看下面的代碼:


清單 8. 將 @Autowired 注釋標(biāo)注在 Setter 方法上
package com.baobaotao;public class Boss {private Car car;private Office office;@Autowiredpublic void setCar(Car car) {this.car = car;}@Autowiredpublic void setOffice(Office office) {this.office = office;}… }

這時(shí),@Autowired 將查找被標(biāo)注的方法的入?yún)㈩愋偷?Bean,并調(diào)用方法自動(dòng)注入這些 Bean。而下面的使用方法則對(duì)構(gòu)造函數(shù)進(jìn)行標(biāo)注:


清單 9. 將 @Autowired 注釋標(biāo)注在構(gòu)造函數(shù)上
package com.baobaotao;public class Boss {private Car car;private Office office;@Autowiredpublic Boss(Car car ,Office office){this.car = car;this.office = office ;}… }

由于 Boss() 構(gòu)造函數(shù)有兩個(gè)入?yún)?#xff0c;分別是 caroffice@Autowired 將分別尋找和它們類型匹配的 Bean,將它們作為Boss(Car car ,Office office) 的入?yún)韯?chuàng)建Boss Bean。


當(dāng)候選 Bean 數(shù)目不為 1 時(shí)的應(yīng)對(duì)方法

在默認(rèn)情況下使用 @Autowired 注釋進(jìn)行自動(dòng)注入時(shí),Spring 容器中匹配的候選 Bean 數(shù)目必須有且僅有一個(gè)。當(dāng)找不到一個(gè)匹配的 Bean 時(shí),Spring 容器將拋出BeanCreationException 異常,并指出必須至少擁有一個(gè)匹配的 Bean。我們可以來做一個(gè)實(shí)驗(yàn):


清單 10. 候選 Bean 數(shù)目為 0 時(shí)
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd "><bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> <bean id="boss" class="com.baobaotao.Boss"/><!-- 將 office Bean 注釋掉 --><!-- <bean id="office" class="com.baobaotao.Office"><property name="officeNo" value="001"/></bean>--><bean id="car" class="com.baobaotao.Car" scope="singleton"><property name="brand" value=" 紅旗 CA72"/><property name="price" value="2000"/></bean> </beans>

由于 office Bean 被注釋掉了,所以 Spring 容器中將沒有類型為Office 的 Bean 了,而 Boss 的 office 屬性標(biāo)注了@Autowired,當(dāng)啟動(dòng) Spring 容器時(shí),異常就產(chǎn)生了。

當(dāng)不能確定 Spring 容器中一定擁有某個(gè)類的 Bean 時(shí),可以在需要自動(dòng)注入該類 Bean 的地方可以使用 @Autowired(required = false),這等于告訴 Spring:在找不到匹配 Bean 時(shí)也不報(bào)錯(cuò)。來看一下具體的例子:


清單 11. 使用 @Autowired(required = false)
package com.baobaotao;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Required;public class Boss {private Car car;private Office office;@Autowiredpublic void setCar(Car car) {this.car = car;}@Autowired(required = false)public void setOffice(Office office) {this.office = office;}… }

當(dāng)然,一般情況下,使用 @Autowired 的地方都是需要注入 Bean 的,使用了自動(dòng)注入而又允許不注入的情況一般僅會(huì)在開發(fā)期或測試期碰到(如為了快速啟動(dòng) Spring 容器,僅引入一些模塊的 Spring 配置文件),所以@Autowired(required = false) 會(huì)很少用到。

和找不到一個(gè)類型匹配 Bean 相反的一個(gè)錯(cuò)誤是:如果 Spring 容器中擁有多個(gè)候選 Bean,Spring 容器在啟動(dòng)時(shí)也會(huì)拋出 BeanCreationException 異常。來看下面的例子:


清單 12. 在 beans.xml 中配置兩個(gè) Office 類型的 Bean
… <bean id="office" class="com.baobaotao.Office"><property name="officeNo" value="001"/> </bean> <bean id="office2" class="com.baobaotao.Office"><property name="officeNo" value="001"/> </bean> …

我們?cè)?Spring 容器中配置了兩個(gè)類型為 Office 類型的 Bean,當(dāng)對(duì) Boss 的office 成員變量進(jìn)行自動(dòng)注入時(shí),Spring 容器將無法確定到底要用哪一個(gè) Bean,因此異常發(fā)生了。

Spring 允許我們通過 @Qualifier 注釋指定注入 Bean 的名稱,這樣歧義就消除了,可以通過下面的方法解決異常:


清單 13. 使用 @Qualifier 注釋指定注入 Bean 的名稱
@Autowired public void setOffice(@Qualifier("office")Office office) {this.office = office; }

@Qualifier("office") 中的 office 是 Bean 的名稱,所以 @Autowired@Qualifier 結(jié)合使用時(shí),自動(dòng)注入的策略就從 byType 轉(zhuǎn)變成 byName 了。@Autowired 可以對(duì)成員變量、方法以及構(gòu)造函數(shù)進(jìn)行注釋,而@Qualifier 的標(biāo)注對(duì)象是成員變量、方法入?yún)ⅰ?gòu)造函數(shù)入?yún)ⅰU怯捎谧⑨寣?duì)象的不同,所以 Spring 不將@Autowired@Qualifier 統(tǒng)一成一個(gè)注釋類。下面是對(duì)成員變量和構(gòu)造函數(shù)入?yún)⑦M(jìn)行注釋的代碼:

對(duì)成員變量進(jìn)行注釋:


清單 14. 對(duì)成員變量使用 @Qualifier 注釋
public class Boss {@Autowiredprivate Car car;@Autowired@Qualifier("office")private Office office;… }

對(duì)構(gòu)造函數(shù)入?yún)⑦M(jìn)行注釋:


清單 15. 對(duì)構(gòu)造函數(shù)變量使用 @Qualifier 注釋
public class Boss {private Car car;private Office office;@Autowiredpublic Boss(Car car , @Qualifier("office")Office office){this.car = car;this.office = office ;} }

@Qualifier 只能和 @Autowired 結(jié)合使用,是對(duì)@Autowired 有益的補(bǔ)充。一般來講,@Qualifier 對(duì)方法簽名中入?yún)⑦M(jìn)行注釋會(huì)降低代碼的可讀性,而對(duì)成員變量注釋則相對(duì)好一些。


使用 JSR-250 的注釋

Spring 不但支持自己定義的 @Autowired 的注釋,還支持幾個(gè)由 JSR-250 規(guī)范定義的注釋,它們分別是@Resource@PostConstruct 以及@PreDestroy

@Resource

@Resource 的作用相當(dāng)于 @Autowired,只不過@Autowired 按 byType 自動(dòng)注入,面 @Resource 默認(rèn)按 byName 自動(dòng)注入罷了。@Resource 有兩個(gè)屬性是比較重要的,分別是 name 和 type,Spring 將@Resource 注釋的 name 屬性解析為 Bean 的名字,而 type 屬性則解析為 Bean 的類型。所以如果使用 name 屬性,則使用 byName 的自動(dòng)注入策略,而使用 type 屬性時(shí)則使用 byType 自動(dòng)注入策略。如果既不指定 name 也不指定 type 屬性,這時(shí)將通過反射機(jī)制使用 byName 自動(dòng)注入策略。

Resource 注釋類位于 Spring 發(fā)布包的 lib/j2ee/common-annotations.jar 類包中,因此在使用之前必須將其加入到項(xiàng)目的類庫中。來看一個(gè)使用@Resource 的例子:


清單 16. 使用 @Resource 注釋的 Boss.java
package com.baobaotao;import javax.annotation.Resource;public class Boss {// 自動(dòng)注入類型為 Car 的 Bean@Resourceprivate Car car;// 自動(dòng)注入 bean 名稱為 office 的 Bean@Resource(name = "office")private Office office; }

一般情況下,我們無需使用類似于 @Resource(type=Car.class) 的注釋方式,因?yàn)?Bean 的類型信息可以通過 Java 反射從代碼中獲取。

要讓 JSR-250 的注釋生效,除了在 Bean 類中標(biāo)注這些注釋外,還需要在 Spring 容器中注冊(cè)一個(gè)負(fù)責(zé)處理這些注釋的 BeanPostProcessor

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>

CommonAnnotationBeanPostProcessor 實(shí)現(xiàn)了BeanPostProcessor 接口,它負(fù)責(zé)掃描使用了 JSR-250 注釋的 Bean,并對(duì)它們進(jìn)行相應(yīng)的操作。

@PostConstruct 和 @PreDestroy

Spring 容器中的 Bean 是有生命周期的,Spring 允許在 Bean 在初始化完成后以及 Bean 銷毀前執(zhí)行特定的操作,您既可以通過實(shí)現(xiàn) InitializingBean/DisposableBean 接口來定制初始化之后 / 銷毀之前的操作方法,也可以通過 <bean> 元素的 init-method/destroy-method 屬性指定初始化之后 / 銷毀之前調(diào)用的操作方法。關(guān)于 Spring 的生命周期,筆者在《精通 Spring 2.x—企業(yè)應(yīng)用開發(fā)精解》第 3 章進(jìn)行了詳細(xì)的描述,有興趣的讀者可以查閱。

JSR-250 為初始化之后/銷毀之前方法的指定定義了兩個(gè)注釋類,分別是 @PostConstruct 和 @PreDestroy,這兩個(gè)注釋只能應(yīng)用于方法上。標(biāo)注了 @PostConstruct 注釋的方法將在類實(shí)例化后調(diào)用,而標(biāo)注了 @PreDestroy 的方法將在類銷毀之前調(diào)用。


清單 17. 使用 @PostConstruct 和 @PreDestroy 注釋的 Boss.java
package com.baobaotao;import javax.annotation.Resource; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy;public class Boss {@Resourceprivate Car car;@Resource(name = "office")private Office office;@PostConstructpublic void postConstruct1(){System.out.println("postConstruct1");}@PreDestroypublic void preDestroy1(){System.out.println("preDestroy1"); }… }

您只需要在方法前標(biāo)注 @PostConstruct@PreDestroy,這些方法就會(huì)在 Bean 初始化后或銷毀之前被 Spring 容器執(zhí)行了。

我們知道,不管是通過實(shí)現(xiàn) InitializingBean/DisposableBean 接口,還是通過 <bean> 元素的init-method/destroy-method 屬性進(jìn)行配置,都只能為 Bean 指定一個(gè)初始化 / 銷毀的方法。但是使用@PostConstruct@PreDestroy 注釋卻可以指定多個(gè)初始化 / 銷毀方法,那些被標(biāo)注@PostConstruct@PreDestroy 注釋的方法都會(huì)在初始化 / 銷毀時(shí)被執(zhí)行。

通過以下的測試代碼,您將可以看到 Bean 的初始化 / 銷毀方法是如何被執(zhí)行的:


清單 18. 測試類代碼
package com.baobaotao;import org.springframework.context.support.ClassPathXmlApplicationContext;public class AnnoIoCTest {public static void main(String[] args) {String[] locations = {"beans.xml"};ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(locations);Boss boss = (Boss) ctx.getBean("boss");System.out.println(boss);ctx.destroy();// 關(guān)閉 Spring 容器,以觸發(fā) Bean 銷毀方法的執(zhí)行} }

這時(shí),您將看到標(biāo)注了 @PostConstructpostConstruct1() 方法將在 Spring 容器啟動(dòng)時(shí),創(chuàng)建 Boss Bean 的時(shí)候被觸發(fā)執(zhí)行,而標(biāo)注了 @PreDestroy 注釋的preDestroy1() 方法將在 Spring 容器關(guān)閉前銷毀Boss Bean 的時(shí)候被觸發(fā)執(zhí)行。


使用 <context:annotation-config/> 簡化配置

Spring 2.1 添加了一個(gè)新的 context 的 Schema 命名空間,該命名空間對(duì)注釋驅(qū)動(dòng)、屬性文件引入、加載期織入等功能提供了便捷的配置。我們知道注釋本身是不會(huì)做任何事情的,它僅提供元數(shù)據(jù)信息。要使元數(shù)據(jù)信息真正起作用,必須讓負(fù)責(zé)處理這些元數(shù)據(jù)的處理器工作起來。

而我們前面所介紹的 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor 就是處理這些注釋元數(shù)據(jù)的處理器。但是直接在 Spring 配置文件中定義這些 Bean 顯得比較笨拙。Spring 為我們提供了一種方便的注冊(cè)這些BeanPostProcessor 的方式,這就是 <context:annotation-config/>。請(qǐng)看下面的配置:


清單 19. 調(diào)整 beans.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-2.5.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"><context:annotation-config/> <bean id="boss" class="com.baobaotao.Boss"/><bean id="office" class="com.baobaotao.Office"><property name="officeNo" value="001"/></bean><bean id="car" class="com.baobaotao.Car" scope="singleton"><property name="brand" value=" 紅旗 CA72"/><property name="price" value="2000"/></bean> </beans>

<context:annotationconfig/> 將隱式地向 Spring 容器注冊(cè) AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorPersistenceAnnotationBeanPostProcessor 以及 equiredAnnotationBeanPostProcessor 這 4 個(gè) BeanPostProcessor。

在配置文件中使用 context 命名空間之前,必須在 <beans> 元素中聲明 context 命名空間。


使用 @Component

雖然我們可以通過 @Autowired@Resource 在 Bean 類中使用自動(dòng)注入功能,但是 Bean 還是在 XML 文件中通過 <bean> 進(jìn)行定義 —— 也就是說,在 XML 配置文件中定義 Bean,通過@Autowired@Resource 為 Bean 的成員變量、方法入?yún)⒒驑?gòu)造函數(shù)入?yún)⑻峁┳詣?dòng)注入的功能。能否也通過注釋定義 Bean,從 XML 配置文件中完全移除 Bean 定義的配置呢?答案是肯定的,我們通過 Spring 2.5 提供的@Component 注釋就可以達(dá)到這個(gè)目標(biāo)了。

下面,我們完全使用注釋定義 Bean 并完成 Bean 之間裝配:


清單 20. 使用 @Component 注釋的 Car.java
package com.baobaotao;import org.springframework.stereotype.Component;@Component public class Car {… }

僅需要在類定義處,使用 @Component 注釋就可以將一個(gè)類定義了 Spring 容器中的 Bean。下面的代碼將Office 定義為一個(gè) Bean:


清單 21. 使用 @Component 注釋的 Office.java
package com.baobaotao;import org.springframework.stereotype.Component;@Component public class Office {private String officeNo = "001";… }

這樣,我們就可以在 Boss 類中通過 @Autowired 注入前面定義的CarOffice Bean 了。


清單 22. 使用 @Component 注釋的 Boss.java
package com.baobaotao;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Required; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component;@Component("boss") public class Boss {@Autowiredprivate Car car;@Autowiredprivate Office office;… }

@Component 有一個(gè)可選的入?yún)?#xff0c;用于指定 Bean 的名稱,在 Boss 中,我們就將 Bean 名稱定義為“boss”。一般情況下,Bean 都是 singleton 的,需要注入 Bean 的地方僅需要通過 byType 策略就可以自動(dòng)注入了,所以大可不必指定 Bean 的名稱。

在使用 @Component 注釋后,Spring 容器必須啟用類掃描機(jī)制以啟用注釋驅(qū)動(dòng) Bean 定義和注釋驅(qū)動(dòng) Bean 自動(dòng)注入的策略。Spring 2.5 對(duì) context 命名空間進(jìn)行了擴(kuò)展,提供了這一功能,請(qǐng)看下面的配置:


清單 23. 簡化版的 beans.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-2.5.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"><context:component-scan base-package="com.baobaotao"/> </beans>

這里,所有通過 <bean> 元素定義 Bean 的配置內(nèi)容已經(jīng)被移除,僅需要添加一行 <context:component-scan/> 配置就解決所有問題了——Spring XML 配置文件得到了極致的簡化(當(dāng)然配置元數(shù)據(jù)還是需要的,只不過以注釋形式存在罷了)。<context:component-scan/> 的 base-package 屬性指定了需要掃描的類包,類包及其遞歸子包中所有的類都會(huì)被處理。

<context:component-scan/> 還允許定義過濾器將基包下的某些類納入或排除。Spring 支持以下 4 種類型的過濾方式,通過下表說明:


表 1. 掃描過濾方式
過濾器類型說明
注釋假如 com.baobaotao.SomeAnnotation 是一個(gè)注釋類,我們可以將使用該注釋的類過濾出來。
類名指定通過全限定類名進(jìn)行過濾,如您可以指定將 com.baobaotao.Boss 納入掃描,而將 com.baobaotao.Car 排除在外。
正則表達(dá)式通過正則表達(dá)式定義過濾的類,如下所示: com\.baobaotao\.Default.*
AspectJ 表達(dá)式通過 AspectJ 表達(dá)式定義過濾的類,如下所示: com. baobaotao..*Service+

下面是一個(gè)簡單的例子:

<context:component-scan base-package="com.baobaotao"><context:include-filter type="regex" expression="com\.baobaotao\.service\..*"/><context:exclude-filter type="aspectj" expression="com.baobaotao.util..*"/> </context:component-scan>

值得注意的是 <context:component-scan/> 配置項(xiàng)不但啟用了對(duì)類包進(jìn)行掃描以實(shí)施注釋驅(qū)動(dòng) Bean 定義的功能,同時(shí)還啟用了注釋驅(qū)動(dòng)自動(dòng)注入的功能(即還隱式地在內(nèi)部注冊(cè)了AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor),因此當(dāng)使用 <context:component-scan/> 后,就可以將 <context:annotation-config/> 移除了。

默認(rèn)情況下通過 @Component 定義的 Bean 都是 singleton 的,如果需要使用其它作用范圍的 Bean,可以通過@Scope 注釋來達(dá)到目標(biāo),如以下代碼所示:


清單 24. 通過 @Scope 指定 Bean 的作用范圍
package com.baobaotao; import org.springframework.context.annotation.Scope; … @Scope("prototype") @Component("boss") public class Boss {… }

這樣,當(dāng)從 Spring 容器中獲取 boss Bean 時(shí),每次返回的都是新的實(shí)例了。


采用具有特殊語義的注釋

Spring 2.5 中除了提供 @Component 注釋外,還定義了幾個(gè)擁有特殊語義的注釋,它們分別是:@Repository@Service@Controller。在目前的 Spring 版本中,這 3 個(gè)注釋和@Component 是等效的,但是從注釋類的命名上,很容易看出這 3 個(gè)注釋分別和持久層、業(yè)務(wù)層和控制層(Web 層)相對(duì)應(yīng)。雖然目前這 3 個(gè)注釋和@Component 相比沒有什么新意,但 Spring 將在以后的版本中為它們添加特殊的功能。所以,如果 Web 應(yīng)用程序采用了經(jīng)典的三層分層結(jié)構(gòu)的話,最好在持久層、業(yè)務(wù)層和控制層分別采用@Repository@Service@Controller 對(duì)分層中的類進(jìn)行注釋,而用 @Component 對(duì)那些比較中立的類進(jìn)行注釋。


注釋配置和 XML 配置的適用場合

是否有了這些 IOC 注釋,我們就可以完全摒除原來 XML 配置的方式呢?答案是否定的。有以下幾點(diǎn)原因:

  • 注釋配置不一定在先天上優(yōu)于 XML 配置。如果 Bean 的依賴關(guān)系是固定的,(如 Service 使用了哪幾個(gè) DAO 類),這種配置信息不會(huì)在部署時(shí)發(fā)生調(diào)整,那么注釋配置優(yōu)于 XML 配置;反之如果這種依賴關(guān)系會(huì)在部署時(shí)發(fā)生調(diào)整,XML 配置顯然又優(yōu)于注釋配置,因?yàn)樽⑨屖菍?duì) Java 源代碼的調(diào)整,您需要重新改寫源代碼并重新編譯才可以實(shí)施調(diào)整。
  • 如果 Bean 不是自己編寫的類(如 JdbcTemplateSessionFactoryBean 等),注釋配置將無法實(shí)施,此時(shí) XML 配置是唯一可用的方式。
  • 注釋配置往往是類級(jí)別的,而 XML 配置則可以表現(xiàn)得更加靈活。比如相比于 @Transaction 事務(wù)注釋,使用 aop/tx 命名空間的事務(wù)配置更加靈活和簡單。

所以在實(shí)現(xiàn)應(yīng)用中,我們往往需要同時(shí)使用注釋配置和 XML 配置,對(duì)于類級(jí)別且不會(huì)發(fā)生變動(dòng)的配置可以優(yōu)先考慮注釋配置;而對(duì)于那些第三方類以及容易發(fā)生調(diào)整的配置則應(yīng)優(yōu)先考慮使用 XML 配置。Spring 會(huì)在具體實(shí)施 Bean 創(chuàng)建和 Bean 注入之前將這兩種配置方式的元信息融合在一起。


小結(jié)

Spring 在 2.1 以后對(duì)注釋配置提供了強(qiáng)力的支持,注釋配置功能成為 Spring 2.5 的最大的亮點(diǎn)之一。合理地使用 Spring 2.5 的注釋配置,可以有效減少配置的工作量,提高程序的內(nèi)聚性。但是這并不意味著傳統(tǒng) XML 配置將走向消亡,在第三方類 Bean 的配置,以及那些諸如數(shù)據(jù)源、緩存池、持久層操作模板類、事務(wù)管理等內(nèi)容的配置上,XML 配置依然擁有不可替代的地位。


參考資料

學(xué)習(xí)

  • Spring 系列:Spring 框架簡介:優(yōu)秀的 Spring 框架入門系列,了解 Spring 框架的基本概念。

  • 輕量級(jí)開發(fā)的成功秘訣,第 3 部分: Spring 露出水面:介紹了在 Spring 框架的輕量級(jí) Ioc 容器。

  • Spring Framework 和 IBM WebSphere Application Server:Interface21 的首席執(zhí)行官 Rod Johnson 和 IBM 的 WebSphere Open Source 主管 Paul Buck 討論了 Spring Framework 通過 IBM WebSphere Application Server 認(rèn)證對(duì) Spring 和 WebSphere 產(chǎn)品系列的開發(fā)人員和客戶有何重要意義。

  • Tiger 中的注釋,第 1 部分: 向 Java 代碼中添加元數(shù)據(jù):解釋了元數(shù)據(jù)如此有用的原因,向您介紹了 Java 語言中的注釋,并研究了 Tiger 的內(nèi)置注釋。

  • Tiger 中的注釋,第 2 部分: 定制注釋:說明了如何創(chuàng)建定制注釋,如何用自己的注釋注解文檔,并進(jìn)一步定制代碼。

獲得產(chǎn)品和技術(shù)

  • Springframework 網(wǎng)站:下載 Spring 框架。

關(guān)于作者

陳雄華,2002 年畢業(yè)于廈門大學(xué)計(jì)算機(jī)與信息工程學(xué)院,獲碩士學(xué)位。是寶寶淘科技有限公司的創(chuàng)始人之一(http://www.baobaotao.com),這是一個(gè)服務(wù)于全國母嬰用戶的綜合性網(wǎng)站,作者負(fù)責(zé)網(wǎng)站整體框架設(shè)計(jì)以及核心代碼開發(fā)的工作。技術(shù)開發(fā)之余,常將經(jīng)驗(yàn)所得行諸于文字,作者是國內(nèi)多個(gè)著名技術(shù)網(wǎng)站的專欄作者,在各大技術(shù)網(wǎng)站、報(bào)刊雜志發(fā)表過數(shù)十篇技術(shù)文章,廣受讀者好評(píng)。于 2005 年出版《精通 JBuilder 2005》,于2007年出版《精通 Spring 2.x--企業(yè)應(yīng)用開發(fā)詳解》,其新作《EXT 2.x開發(fā)詳解――AJAX和Web頁面布局王者至尊》即將出版。

?

=============http://www.cnblogs.com/jiangchao/archive/2010/08/30/1812528.html

Spring注入方式及用到的注解 -----@Component,@Service,@Controller,@Repository

注入方式:

把DAO實(shí)現(xiàn)類注入到service實(shí)現(xiàn)類中,把service的接口(注意不要是service的實(shí)現(xiàn)類)注入到action中,注

入時(shí)不要new 這個(gè)注入的類,因?yàn)閟pring會(huì)自動(dòng)注入,如果手動(dòng)再new的話會(huì)出現(xiàn)錯(cuò)誤,然后屬性加上

@Autowired后不需要getter()和setter()方法,Spring也會(huì)自動(dòng)注入。至于更具體的內(nèi)容,等對(duì)注入的方式更

加熟練后會(huì)做個(gè)完整的例子上來。

注解:

在spring的配置文件里面只需要加上<context:annotation-config/> 和<context:component-scan base-package="需要實(shí)現(xiàn)注入的類所在包"/>,可以使用base-package="*"表示全部的類。??

<context:component-scan base-package=”com.eric.spring”>

其中base-package為需要掃描的包(含所有子包)

在接口前面標(biāo)上@Autowired和@Qualifier注釋使得接口可以被容器注入,當(dāng)接口存在兩個(gè)實(shí)現(xiàn)類的時(shí)候必須指定其中一個(gè)來注入,使用實(shí)現(xiàn)類首字母小寫的字符串來注入,如:

  • ??? @Autowired?? ??
  • ??
  • ????@Qualifier("chinese")??? ??
  • ??
  • ????private Man man;???
  • 否則可以省略,只寫@Autowired?? 。

    @Service服務(wù)層組件,用于標(biāo)注業(yè)務(wù)層組件,表示定義一個(gè)bean,自動(dòng)根據(jù)bean的類名實(shí)例化一個(gè)首寫字母為小寫的bean,例如Chinese實(shí)例化為chinese,如果需要自己改名字則:@Service("你自己改的bean名")。??

    @Controller用于標(biāo)注控制層組件(如struts中的action)

    @Repository持久層組件,用于標(biāo)注數(shù)據(jù)訪問組件,即DAO組件

    @Component泛指組件,當(dāng)組件不好歸類的時(shí)候,我們可以使用這個(gè)注解進(jìn)行標(biāo)注。


    @Service
    public class VentorServiceImpl implements iVentorService {
    }

    @Repository
    public class VentorDaoImpl implements iVentorDao {
    }

    getBean 的默認(rèn)名稱是類名(頭字母小寫),如果想自定義,可以@Service(“aaaaa”) 這樣來指定,這種

    bean默認(rèn)是單例的,如果想改變,可以使用@Service(“beanName”) @Scope(“prototype”)來改變。

    可以使用以下方式指定初始化方法和銷毀方法(方法名任意):

    @PostConstruct

    public void init() {

    }

    @PreDestroy

    public void destory() {

    }

    ?

    ?

    總結(jié)

    以上是生活随笔為你收集整理的Spring使用注释的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。