欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
使用 Spring 2.5 注釋驅動(dòng)的 IoC 功能

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

級別: 初級

陳 雄華 (quickselect@163.com), 技術(shù)總監, 寶寶淘網(wǎng)絡(luò )科技有限公司

2008 年 2 月 28 日

基于注釋?zhuān)ˋnnotation)的配置有越來(lái)越流行的趨勢,Spring 2.5 順應這種趨勢,提供了完全基于注釋配置 Bean、裝配 Bean 的功能,您可以使用基于注釋的 Spring IoC 替換原來(lái)基于 XML 的配置。本文通過(guò)實(shí)例詳細講述了 Spring 2.5 基于注釋 IoC 功能的使用。

概述

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

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

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





原來(lái)我們是怎么做的

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

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


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

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


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

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


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

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


清單 4. beans.xml 將以上三個(gè)類(lèi)配置成 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>                        

當我們運行以下代碼時(shí),控制臺將正確打出 boss 的信息:


清單 5. 測試類(lèi):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);                        }                        }                        

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





回頁(yè)首


使用 @Autowired 注釋

Spring 2.5 引入了 @Autowired 注釋?zhuān)梢詫︻?lèi)成員變量、方法及構造函數進(jìn)行標注,完成自動(dòng)裝配的工作。來(lái)看一下使用 @Autowired 進(jìn)行成員變量自動(dòng)注入的代碼:


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

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


清單 7. 讓 @Autowired 注釋工作起來(lái)
                        <?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)起作用,對標注 @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>                        

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

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

當然,您也可以通過(guò) @Autowired 對方法或構造函數進(jìn)行標注,來(lái)看下面的代碼:


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

這時(shí),@Autowired 將查找被標注的方法的入參類(lèi)型的 Bean,并調用方法自動(dòng)注入這些 Bean。而下面的使用方法則對構造函數進(jìn)行標注:


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

由于 Boss() 構造函數有兩個(gè)入參,分別是 caroffice,@Autowired 將分別尋找和它們類(lèi)型匹配的 Bean,將它們作為 Boss(Car car ,Office office) 的入參來(lái)創(chuàng )建 Boss Bean。





回頁(yè)首


當候選 Bean 數目不為 1 時(shí)的應對方法

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


清單 10. 候選 Bean 數目為 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 容器中將沒(méi)有類(lèi)型為 Office 的 Bean 了,而 Boss 的 office 屬性標注了 @Autowired,當啟動(dòng) Spring 容器時(shí),異常就產(chǎn)生了。

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


清單 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;                        @Autowired                        public void setCar(Car car) {                        this.car = car;                        }                        @Autowired(required = false)                        public void setOffice(Office office) {                        this.office = office;                        }                        …                        }                        

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

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


清單 12. 在 beans.xml 中配置兩個(gè) Office 類(lèi)型的 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>                        …                        

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

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


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

@Qualifier("office") 中的 office 是 Bean 的名稱(chēng),所以 @Autowired@Qualifier 結合使用時(shí),自動(dòng)注入的策略就從 byType 轉變成 byName 了。@Autowired 可以對成員變量、方法以及構造函數進(jìn)行注釋?zhuān)?@Qualifier 的標注對象是成員變量、方法入參、構造函數入參。正是由于注釋對象的不同,所以 Spring 不將 @Autowired@Qualifier 統一成一個(gè)注釋類(lèi)。下面是對成員變量和構造函數入參進(jìn)行注釋的代碼:

對成員變量進(jìn)行注釋?zhuān)?/p>
清單 14. 對成員變量使用 @Qualifier 注釋

                        public class Boss {                        @Autowired                        private Car car;                        @Autowired                        @Qualifier("office")                        private Office office;                        …                        }                        

對構造函數入參進(jìn)行注釋?zhuān)?/p>
清單 15. 對構造函數變量使用 @Qualifier 注釋

                        public class Boss {                        private Car car;                        private Office office;                        @Autowired                        public Boss(Car car , @Qualifier("office")Office office){                        this.car = car;                        this.office = office ;                        }                        }                        

@Qualifier 只能和 @Autowired 結合使用,是對 @Autowired 有益的補充。一般來(lái)講,@Qualifier 對方法簽名中入參進(jìn)行注釋會(huì )降低代碼的可讀性,而對成員變量注釋則相對好一些。






使用 JSR-250 的注釋

Spring 不但支持自己定義的 @Autowired 的注釋?zhuān)€支持幾個(gè)由 JSR-250 規范定義的注釋?zhuān)鼈兎謩e是 @Resource、@PostConstruct 以及 @PreDestroy。

@Resource

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

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


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

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

要讓 JSR-250 的注釋生效,除了在 Bean 類(lèi)中標注這些注釋外,還需要在 Spring 容器中注冊一個(gè)負責處理這些注釋的 BeanPostProcessor

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

CommonAnnotationBeanPostProcessor 實(shí)現了 BeanPostProcessor 接口,它負責掃描使用了 JSR-250 注釋的 Bean,并對它們進(jìn)行相應的操作。

@PostConstruct 和 @PreDestroy

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

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


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

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

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

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


清單 18. 測試類(lèi)代碼
                        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 銷(xiāo)毀方法的執行                        }                        }                        

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





使用 <context:annotation-config/> 簡(jiǎn)化配置

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

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


清單 19. 調整 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.xsd                        http://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 容器注冊 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及 equiredAnnotationBeanPostProcessor 這 4 個(gè) BeanPostProcessor。

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





使用 @Component

雖然我們可以通過(guò) @Autowired@Resource 在 Bean 類(lèi)中使用自動(dòng)注入功能,但是 Bean 還是在 XML 文件中通過(guò) <bean> 進(jìn)行定義 —— 也就是說(shuō),在 XML 配置文件中定義 Bean,通過(guò) @Autowired@Resource 為 Bean 的成員變量、方法入參或構造函數入參提供自動(dòng)注入的功能。能否也通過(guò)注釋定義 Bean,從 XML 配置文件中完全移除 Bean 定義的配置呢?答案是肯定的,我們通過(guò) Spring 2.5 提供的 @Component 注釋就可以達到這個(gè)目標了。

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


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

僅需要在類(lèi)定義處,使用 @Component 注釋就可以將一個(gè)類(lèi)定義了 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 類(lèi)中通過(guò) @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 {                        @Autowired                        private Car car;                        @Autowired                        private Office office;                        …                        }                        

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

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


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

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

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


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

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

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

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


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

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





采用具有特殊語(yǔ)義的注釋

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





注釋配置和 XML 配置的適用場(chǎng)合

是否有了這些 IOC 注釋?zhuān)覀兙涂梢酝耆鸪瓉?lái) XML 配置的方式呢?答案是否定的。有以下幾點(diǎn)原因:

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

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





小結

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


本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Spring2.X的IOC支持
Spring 之 注解詳解
Spring——容器,注入(配置和注解兩種方式)
Spring Annotation 筆記——IOC篇
spring2中基于注釋的配置方式淺析
Struts2整合Spring從xml到注解
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久