Spring的核心機(jī)制及容器_第1頁
Spring的核心機(jī)制及容器_第2頁
Spring的核心機(jī)制及容器_第3頁
Spring的核心機(jī)制及容器_第4頁
Spring的核心機(jī)制及容器_第5頁
已閱讀5頁,還剩69頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Spring的核心機(jī)制及容器第1頁/共74頁14.1.1依賴注入的概念創(chuàng)建包“erfaces.impl”,在該包中定義Person的實(shí)現(xiàn)類Man,代碼如下:

packageerfaces.impl;importerfaces.Food;importerfaces.Person;/**Person接口的具體實(shí)現(xiàn)類*/publicclassManimplementsPerson{ //定義Food接口私有屬性,面向Food接口編程,而不是具體的實(shí)現(xiàn)類 privateFoodfood; //構(gòu)建

setter方法,必須要有,后面會(huì)講解為什么 publicvoidsetFood(Foodfood){ this.food=food; } //實(shí)現(xiàn)Person接口eatFood方法 publicvoideatFood(){ System.out.println(food.eat()); }}第2頁/共74頁14.1.1依賴注入的概念定義Food的一個(gè)實(shí)現(xiàn)類Apple,代碼如下:

packageerfaces.impl;importerfaces.Food;publicclassAppleimplementsFood{ publicStringeat(){ return"正在吃蘋果..."; }}

在src下編寫Spring的配置文件config.xml,使用Spring的配置文件將Person實(shí)例和Food實(shí)例組織在一起,配置內(nèi)容。第3頁/共74頁14.1.1依賴注入的概念下面就可以編寫測(cè)試類了,代碼如下:

packageorg.test;importerfaces.Person;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.FileSystemXmlApplicationContext;publicclassTest{publicstaticvoidmain(String[]args){ //創(chuàng)建ApplicationContext對(duì)象,參數(shù)為配置文件放置的位置 ApplicationContextcontext= newFileSystemXmlApplicationContext("/WebRoot/WEB-INF/classes/config.xml"); //通過Personbean的id來獲取bean實(shí)例,面向接口編程,因此此處強(qiáng)制類型轉(zhuǎn)換為接口類型 Personp=(Person)context.getBean("man"); //直接執(zhí)行Person的eatFood()方法 p.eatFood(); }}第4頁/共74頁14.1.1依賴注入的概念運(yùn)行主程序,輸出結(jié)果,代碼如下:

正在吃蘋果...

在主程序中,調(diào)用了Person的eatFood()方法,該方法的方法體內(nèi)需要使用Food的實(shí)例,按照通常的方式,在Person實(shí)例的eatFood()方法中,應(yīng)該這樣實(shí)現(xiàn):

//創(chuàng)建Food實(shí)例food=newApple();//獲得Food實(shí)例的eat方法返回值System.out.println(food.eat());第5頁/共74頁14.1.1依賴注入的概念如果需要改寫Food的實(shí)現(xiàn)類,或者提供另一個(gè)實(shí)現(xiàn)類給Person實(shí)例使用,Person接口和Man實(shí)現(xiàn)類都無須改變,只需提供另一個(gè)Food的實(shí)現(xiàn),然后對(duì)配置文件進(jìn)行簡(jiǎn)單的修改即可。例如,我們現(xiàn)在新建另一個(gè)Food的實(shí)現(xiàn)類Orange,代碼如下:

packageerfaces.impl;importerfaces.Food;/**定義Orange類,實(shí)現(xiàn)Food接口*/publicclassOrangeimplementsFood{ /**實(shí)現(xiàn)接口吃的方法*/ publicStringeat(){ return"正在吃橘子..."; }}第6頁/共74頁14.1.1依賴注入的概念修改配置文件config.xml,增加orange的Bean,代碼如下:

<!--定義orangebean,Food接口的實(shí)現(xiàn)類

--><beanid="orange"class="erfaces.impl.orange"></bean>

該行重新定義了一個(gè)Food的實(shí)現(xiàn):orange,然后修改man的bean配置,將原來傳入apple的地方改為傳入orange。也就是將:

<reflocal="apple"/>

改成:

<reflocal="orange"/>

再次運(yùn)行主程序,輸出結(jié)果如下:

正在吃橘子...第7頁/共74頁14.1.2依賴注入的兩種方式前面講解了依賴注入的概念,本節(jié)將介紹依賴注入的兩種方式:set注入及構(gòu)造注入。其中,set注入已經(jīng)在HelloWorld程序中及上面的程序中應(yīng)用過了,使用方法非常簡(jiǎn)單,需要為被注入的屬性或類構(gòu)建setter方法,例如在HelloWorld.java中:

packageorg.model;publicclassHelloWorld{ privateStringmessage; publicStringgetMessage(){ returnmessage; }

publicvoidsetMessage(Stringmessage){ this.message=message; }}第8頁/共74頁14.1.2依賴注入的兩種方式然后通過配置文件的Bean來為其注入值:

<beanid="HelloWorld"class="org.model.HelloWorld"> <!--這里在注入值的時(shí)候必須保證HelloWorld類中有message的setter方法

--> <propertyname="message"> <value>HelloWorld!</value> </property></bean>

第9頁/共74頁14.1.2依賴注入的兩種方式這樣設(shè)置后就可以調(diào)用HelloWorld的對(duì)象來調(diào)用getter方法,獲取為message設(shè)置的值了。同樣地,在Man.java中:

packageerfaces.impl;importerfaces.Food;importerfaces.Person;/**Person接口的具體實(shí)現(xiàn)類*/publicclassManimplementsPerson{ //定義Food接口私有屬性,面向Food接口編程,而不是具體的實(shí)現(xiàn)類 privateFoodfood; //設(shè)置依賴注入所需的setter方法,這就解釋了為什么必須有setter方法

publicvoidsetFood(Foodfood){ this.food=food; } //實(shí)現(xiàn)Person接口eatFood方法 publicvoideatFood(){ System.out.println(food.eat()); }}第10頁/共74頁14.1.2依賴注入的兩種方式通過配置文件對(duì)food進(jìn)行依賴注入:構(gòu)造注入,是指在接受注入的類中定義一個(gè)構(gòu)造方法,并在構(gòu)造方法的參數(shù)中定義需要注入的元素。下面就把HelloWorld實(shí)例修改為應(yīng)用構(gòu)造注入來為元素設(shè)值。具體步驟是:首先,修改HelloWorld.java類,在該類中增加一個(gè)構(gòu)造方法,然后再修改配置文件config.xml,最后測(cè)試程序。HelloWorld.java類修改為:

packageorg.model;publicclassHelloWorld{ privateStringmessage; publicHelloWorld(Stringmessage){ this.message=message; } publicStringgetMessage(){ returnmessage; }}第11頁/共74頁14.1.2依賴注入的兩種方式config.xml修改為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="HelloWorld"class="org.model.HelloWorld"> <constructor-argindex="0"> <value>HelloWorld</value> </constructor-arg> </bean></beans>第12頁/共74頁14.1.2依賴注入的兩種方式其中,“constructor-arg”用來表示通過構(gòu)造方式來進(jìn)行依賴注入,“index="0"”表示構(gòu)造方法中的第一個(gè)參數(shù),如果只有一個(gè)參數(shù),可以省略不寫,如果有多個(gè)參數(shù),就直接重復(fù)配置“constructor-arg”即可,不過要改變“index”的值,例如,如果在“HelloWorld”類中還有一個(gè)參數(shù)“mess”,并且通過構(gòu)造方法為其注入值:

publicHelloWorld(Stringmessage,Stringmess){ this.message=message; this.mess=mess;}

那么,只需在配置文件config.xml中加上一個(gè)“constructor-arg”:

<constructor-argindex="1"> <value>HelloYabber</value></constructor-arg>第13頁/共74頁14.1.3兩種注入方式的比較在開發(fā)過程中,set注入和構(gòu)造注入都是會(huì)經(jīng)常用到的,這兩種依賴注入的方式并沒有絕對(duì)的好壞,只是使用的場(chǎng)合有所不同而已。使用構(gòu)造注入可以在構(gòu)建對(duì)象的同時(shí)一并完成依賴關(guān)系的建立,所以,如果要建立的對(duì)象的關(guān)系很多,使用構(gòu)造注入就會(huì)在構(gòu)造方法上留下很多的參數(shù),是非常不易閱讀的,這時(shí)建議使用set注入。然而,用set注入由于提供了setXx()方法,所以不能保證相關(guān)的數(shù)據(jù)在執(zhí)行時(shí)不被更改設(shè)定,因此,如果想要讓一些數(shù)據(jù)變?yōu)橹蛔x或私有,使用構(gòu)造注入會(huì)是個(gè)很好的選擇。第14頁/共74頁14.2Spring容器14.2.1Bean的定義Bean是描述Java的軟件組件模型,其定義在Spring配置文件的根元素<beans>下,<bean>元素是<beans>元素的子元素,在根元素<beans>下可以包含多個(gè)<bean>子元素。每個(gè)<bean>可以完成一個(gè)簡(jiǎn)單的功能,也可以完成一個(gè)復(fù)雜的功能,<bean>之間可以互相協(xié)同工作,完成復(fù)雜的關(guān)系。第15頁/共74頁14.2.2Bean的基本屬性在HelloWorld實(shí)例中,config.xml中的Bean的配置如下:

<beanid="HelloWorld"class="org.model.HelloWorld"> <propertyname="message"> <value>HelloYabber!</value> </property></bean>

在Bean中有一個(gè)id屬性及class屬性,這個(gè)id唯一標(biāo)識(shí)了該Bean。在配置文件中,不能有重復(fù)的Bean的id,因?yàn)樵诖a中通過BeanFactory或ApplicationContext來獲取Bean的實(shí)例時(shí),都要用它來作為唯一索引:

HelloWorldhelloWorld=(HelloWorld)ac.getBean("HelloWorld");第16頁/共74頁14.2.2Bean的基本屬性1.Bean的id屬性為Bean指定別名可以用name屬性來完成,如果需要為Bean指定多個(gè)別名,可以在name屬性中使用逗號(hào)(,)、分號(hào)(;)或空格來分隔多個(gè)別名,在程序中可以通過任意一個(gè)別名訪問該Bean實(shí)例。例如,id為“HelloWorld”的Bean,其別名為:

<beanid="HelloWorld"name="a;b;c"class="org.model.HelloWorld"> <propertyname="message"> <value>HelloYabber!</value> </property> </bean>則在程序中可以利用“a”、“b”、“c”任意一個(gè)來獲取Bean的實(shí)例:

HelloWorldhelloWorld=(HelloWorld)ac.getBean("a");或HelloWorldhelloWorld=(HelloWorld)ac.getBean("b");或HelloWorldhelloWorld=(HelloWorld)ac.getBean("c");

以上三種方法均可完成Bean實(shí)例的獲取。第17頁/共74頁14.2.2Bean的基本屬性2.Bean的class屬性可以看出,每個(gè)Bean都會(huì)指定class屬性,class屬性指明了Bean的來源,即Bean的實(shí)際路徑,注意,這里要寫出完整的包名+類名。例如:

<beanid="HelloWorld"name="a;b;c"class="org.model.HelloWorld">

class屬性非常簡(jiǎn)單,這里就不過多介紹了。3.Bean的scope屬性scope屬性用于指定Bean的作用域,Spring支持5種作用域,這5種作用域如下:singleton:?jiǎn)卫J?,?dāng)定義該模式時(shí),在容器分配Bean的時(shí)候,它總是返回同一個(gè)實(shí)例。該模式是默認(rèn)的,即不定義scope時(shí)的模式。prototype:原型模式,即每次通過容器的getBean方法獲取Bean的實(shí)例時(shí),都將產(chǎn)生信息的Bean實(shí)例。第18頁/共74頁14.2.2Bean的基本屬性request:對(duì)于每次HTTP請(qǐng)求中,使用request定義的Bean都將產(chǎn)生一個(gè)新實(shí)例,即每次HTTP請(qǐng)求將會(huì)產(chǎn)生不同的Bean實(shí)例。只有在Web應(yīng)用中使用Spring時(shí),該作用域有效。session:對(duì)于每次HTTPSession請(qǐng)求中,使用session定義的Bean都將產(chǎn)生一個(gè)新實(shí)例,即每次HTTPSession請(qǐng)求將會(huì)產(chǎn)生不同的Bean實(shí)例。只有在Web應(yīng)用中使用Spring時(shí),該作用域有效。globalsession:每個(gè)全局的HttpSession對(duì)應(yīng)一個(gè)Bean實(shí)例。典型情況下,僅在使用portletcontext的時(shí)候有效。只有在Web應(yīng)用中使用Spring時(shí),該作用域才有效。第19頁/共74頁14.2.2Bean的基本屬性比較常用的是前兩種作用域,即singleton及prototype。下面舉例說明這兩種作用域的差別。仍然是對(duì)HelloWorld程序進(jìn)行修改,在配置文件config.xml中這樣配置:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="HelloWorld1"class="org.model.HelloWorld"></bean> <beanid="HelloWorld2"class="org.model.HelloWorld"scope="prototype"></bean></beans>

在“HelloWorld1”Bean中沒有定義“scope”屬性,即默認(rèn)的“singleton”單例模式?!癏elloWorld2”Bean中指定作用域?yàn)椤皃rototype”,即原型模式。HelloWorld.java類不變,編寫測(cè)試類代碼。第20頁/共74頁14.2.2Bean的基本屬性運(yùn)行該應(yīng)用程序,控制臺(tái)輸出如圖14.1所示。從輸出內(nèi)容可以發(fā)現(xiàn),應(yīng)用單例模式得到的Bean實(shí)例永遠(yuǎn)是同一實(shí)例,而原型模式則是不同的實(shí)例。圖14.1控制臺(tái)輸出第21頁/共74頁14.2.2Bean的基本屬性4.Bean的property在Spring的依賴注入中,是應(yīng)用Bean的子元素<property>來為屬性進(jìn)行設(shè)值的:

<beanid="HelloWorld"class="org.model.HelloWorld">

<propertyname="message"> <value>HelloWorld!</value> </property></bean>如果要為屬性設(shè)置“null”,有兩種方法。第一種直接用value元素指定:

<beanid="HelloWorld"class="org.model.HelloWorld">

<propertyname="message"> <value>null</value> </property></bean>第22頁/共74頁14.2.2Bean的基本屬性第二種方法直接用<null/>:

<beanid="HelloWorld"class="org.model.HelloWorld">

<propertyname="message"> <null/> </property></bean>第23頁/共74頁14.2.3Bean的生命周期

1.Bean的定義Bean的定義在前面的實(shí)例中已經(jīng)應(yīng)用很多了,從基本的HelloWorld程序中就可以基本看出Bean的定義,這里就不再列舉其定義形式,但值得一提的是,在一個(gè)大的應(yīng)用中,會(huì)有很多的Bean需要在配置文件中定義,這樣配置文件就會(huì)很大,變得不易閱讀及維護(hù),這時(shí)可以把相關(guān)的Bean放置在一個(gè)配置文件中,創(chuàng)建多個(gè)配置文件。2.Bean的初始化在Spring中,Bean完成全部屬性的設(shè)置后,Spring中的bean的初始化回調(diào)有兩種方法,一種是在配置文件中聲明“init-method="init"”,然后在HelloWorld類中寫一個(gè)init()方法來初始化;另一種是實(shí)現(xiàn)InitializingBean接口,然后覆蓋其afterPropertiesSet()方法。知道了初始化過程中會(huì)應(yīng)用這兩種方法,就可以在Bean的初始化過程中讓其執(zhí)行特定行為。第24頁/共74頁14.2.3Bean的生命周期

下面介紹這兩種方法的使用方式。第一種方式如下:(1)在HelloWorld類中增加一個(gè)init()方法。代碼如下:

packageorg.model;publicclassHelloWorld{ privateStringmessage; publicStringgetMessage(){ returnmessage; } publicvoidsetMessage(Stringmessage){ this.message=message; } publicvoidinit(){ //利用該方法修改message的值 this.setMessage("HelloYabber"); }}

第25頁/共74頁14.2.3Bean的生命周期

(2)修改配置文件config.xml,指定Bean中要初始化的方法為init(),代碼如下:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="HelloWorld"class="org.model.HelloWorld"init-method="init"> <propertyname="message"> <value>HelloWorld</value> </property> </bean></beans>

第26頁/共74頁14.2.3Bean的生命周期

(3)編寫測(cè)試類,輸出HelloWorld中message的值,代碼如下:

packageorg.test;importorg.model.HelloWorld;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.FileSystemXmlApplicationContext;publicclassTest{ publicstaticvoidmain(String[]args){ ApplicationContextac= newFileSystemXmlApplicationContext("/WebRoot/WEB-INF/classes/config.xml"); HelloWorldhelloWorld=(HelloWorld)ac.getBean("HelloWorld"); System.out.println(helloWorld.getMessage()); }}第27頁/共74頁14.2.3Bean的生命周期

運(yùn)行該程序,控制臺(tái)輸出如圖14.2所示。可以發(fā)現(xiàn),初始化方法的調(diào)用是在Bean初始化的后期執(zhí)行的,改變了message的賦值,故輸出為“HelloYabber”。圖14.2控制臺(tái)輸出第28頁/共74頁14.2.3Bean的生命周期

第二種方式,實(shí)現(xiàn)InitializingBean接口,并覆蓋其“afterPropertiesSet()”方法。(1)修改HelloWorld.java,讓其實(shí)現(xiàn)InitializingBean接口,并覆蓋其“afterPropertiesSet()”方法。代碼實(shí)現(xiàn)為:

packageorg.model;importorg.springframework.beans.factory.InitializingBean;publicclassHelloWorldimplementsInitializingBean{ privateStringmessage; publicStringgetMessage(){ returnmessage; } publicvoidsetMessage(Stringmessage){ this.message=message; } publicvoidafterPropertiesSet()throwsException{ this.setMessage("HelloYabber"); }}第29頁/共74頁14.2.3Bean的生命周期

(2)修改config.xml配置文件,代碼如下:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="HelloWorld"class="org.model.HelloWorld"> <propertyname="message"> <value>HelloWorld</value> </property> </bean></beans>第30頁/共74頁14.2.3Bean的生命周期

3.Bean的應(yīng)用Bean的應(yīng)用非常簡(jiǎn)單,在Spring中有兩種使用Bean的方式。第一種,使用BeanFactory:

//在ClassPath下尋找,由于配置文件就是放在ClassPath下,故可以直接找到ClassPathResourceres=newClassPathResource("config.xml");XmlBeanFactoryfactory=newXmlBeanFactory(res);HelloWorldhelloWorld=(HelloWorld)factory.getBean("HelloWorld");System.out.println(helloWorld.getMessage());

第二種,使用ApplicationContext:

ApplicationContextac= newFileSystemXmlApplicationContext("/WebRoot/WEB-INF/classes/config.xml");HelloWorldhelloWorld=(HelloWorld)ac.getBean("HelloWorld");System.out.println(helloWorld.getMessage());第31頁/共74頁14.2.3Bean的生命周期

4.Bean的銷毀首先介紹第一種方式。(1)在HelloWorld類中增加一個(gè)cleanup()方法。代碼如下:

packageorg.model;publicclassHelloWorldDestroy{ privateStringmessage; publicStringgetMessage(){ returnmessage; } publicvoidsetMessage(Stringmessage){ this.message=message; } publicvoidcleanup(){ this.setMessage("HelloWorld!"); System.out.println("銷毀之前要調(diào)用!"); }}第32頁/共74頁14.2.3Bean的生命周期

(2)修改config.xml配置文件,代碼如下:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="HelloWorld"class="org.model.HelloWorldDestroy"destroy-method="cleanup"> <propertyname="message"> <value>HelloWorld</value> </property> </bean></beans>第33頁/共74頁14.2.3Bean的生命周期

(3)編寫測(cè)試類,輸出message的值,代碼如下:

packageorg.test;importorg.model.HelloWorldDestroy;importorg.springframework.context.support.AbstractApplicationContext;importorg.springframework.context.support.FileSystemXmlApplicationContext;publicclassTest{ publicstaticvoidmain(String[]args){ AbstractApplicationContextac= newFileSystemXmlApplicationContext("/WebRoot/WEB-INF/classes/config.xml"); HelloWorldDestroyhelloWorld=(HelloWorldDestroy)ac.getBean("HelloWorld"); System.out.println(helloWorld.getMessage()); //為Spring容器注冊(cè)關(guān)閉鉤子,程序?qū)?huì)在推出JVM之前關(guān)閉Spring容器 ac.registerShutdownHook(); }}第34頁/共74頁14.2.3Bean的生命周期

運(yùn)行程序,控制臺(tái)輸出結(jié)果如圖14.3所示。圖14.3控制臺(tái)輸出結(jié)果第35頁/共74頁14.2.3Bean的生命周期

第二種方式,實(shí)現(xiàn)DisposableBean接口,并覆蓋其destroy()方法。(1)修改HelloWorldDestroy.java,讓其實(shí)現(xiàn)DisposableBean接口,并覆蓋其“destroy()”方法。代碼實(shí)現(xiàn)為:

packageorg.model;importorg.springframework.beans.factory.DisposableBean;publicclassHelloWorldDestroyimplementsDisposableBean{ privateStringmessage; publicStringgetMessage(){ returnmessage; } publicvoidsetMessage(Stringmessage){ this.message=message; } publicvoiddestroy()throwsException{ System.out.println("該句在銷毀之前要顯示!"); }}第36頁/共74頁14.2.3Bean的生命周期

(2)配置文件config.xml修改為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="HelloWorld"class="org.model.HelloWorldDestroy"> <propertyname="message"> <value>HelloWorld</value> </property> </bean></beans>第37頁/共74頁14.2.4Bean的管理1.BeanFactory在Spring中有幾種BeanFactory的實(shí)現(xiàn),其中最常用的是org.springframework.bean.factory.xml.XmlBeanFactory。它根據(jù)XML文件中的定義裝載Bean。要?jiǎng)?chuàng)建XmlBeanFactory,需要傳遞一個(gè)ClassPathResource對(duì)象給構(gòu)造方法。例如,下面的代碼片段獲取一個(gè)BeanFactory對(duì)象:

//在ClassPath下尋找,由于配置文件就是放在ClassPath下,故可以直接找到ClassPathResourceres=newClassPathResource("config.xml");BeanFactoryfactory=newXmlBeanFactory(res);為了從BeanFactory得到Bean,只要簡(jiǎn)單地調(diào)用getBean()方法,把需要的Bean的名字當(dāng)做參數(shù)傳遞進(jìn)去就行了。由于得到的是Object類型,所以要進(jìn)行強(qiáng)制類型轉(zhuǎn)化:

HelloWorldhelloWorld=(HelloWorld)factory.getBean("HelloWorld");第38頁/共74頁14.2.4Bean的管理2.ApplicationContextBeanFactory對(duì)簡(jiǎn)單應(yīng)用來說已經(jīng)很好了,但是為了獲得Spring框架的強(qiáng)大功能,需要使用Spring更加高級(jí)的容器ApplicationContext(應(yīng)用上下文)。表面上看,ApplicationContext和BeanFactory差不多,兩者都是載入Bean的定義信息,裝配Bean,根據(jù)需要分發(fā)Bean,但是ApplicationContext提供了更多的功能:

應(yīng)用上下文提供了文本信息解析工具,包括對(duì)國際化的支持。

應(yīng)用上下文提供了載入文本資源的通用方法,如載入圖片。

應(yīng)用上下文可以向注冊(cè)為監(jiān)聽器的Bean發(fā)送事件。第39頁/共74頁14.2.4Bean的管理在ApplicationContext的諸多實(shí)現(xiàn)中,有三個(gè)常用的實(shí)現(xiàn):ClassPathXmlApplicationContext:從類路徑中的XML文件載入上下文定義信息,把上下文定義文件當(dāng)成類路徑資源。FileSystemXmlApplicationContext:從文件系統(tǒng)中的XML文件載入上下文定義信息。XmlWebApplicationContext:從Web系統(tǒng)中的XML文件載入上下文定義信息。例如:

ApplicationContextcontext=newFileSystemXmlApplicationContext("c:/server.xml");ApplicationContextcontext=newClassPathApplicationContext("server.xml");ApplicationContextcontext= WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());

FileSystemXmlApplicationContext和ClassPathXmlApplicationContext的區(qū)別是:FileSystemXmlApplicationContext只能在指定的路徑中尋找server.xml文件,而ClassPathXmlApplicationContext可以在整個(gè)類路徑中尋找foo.xml。第40頁/共74頁14.2.5Bean的依賴關(guān)系Bean的依賴關(guān)系是指當(dāng)為一個(gè)Bean的屬性賦值時(shí)要應(yīng)用到另外的Bean,這種情況也稱Bean的引用。例如,有這樣的一個(gè)類DateClass.java:

packageorg.model;importjava.util.Date;publicclassDateClass{ privateDatedate; publicDategetDate(){ returndate; } publicvoidsetDate(Datedate){ this.date=date; }}

第41頁/共74頁14.2.5Bean的依賴關(guān)系在配置文件中為其注入“date”值時(shí),引用了其他Bean,代碼為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="getDate"class="org.model.DateClass">

<propertyname="date"> <reflocal="d"/> </property> </bean>

<beanid="d"class="java.util.Date"></bean></beans>第42頁/共74頁14.2.5Bean的依賴關(guān)系編輯測(cè)試程序Test.java:

packageorg.test;importorg.model.DateClass;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.FileSystemXmlApplicationContext;publicclassTest{ publicstaticvoidmain(String[]args){ ApplicationContextac= newFileSystemXmlApplicationContext("/WebRoot/WEB-INF/classes/config.xml"); DateClassdc=(DateClass)ac.getBean("getDate"); System.out.println(dc.getDate()); }}第43頁/共74頁14.2.5Bean的依賴關(guān)系運(yùn)行程序,控制臺(tái)輸出如圖14.4所示??刂婆_(tái)打印出了本機(jī)的當(dāng)前時(shí)間,在“getDate”的Bean中引用了“d”Bean,也就為DateClass類中的屬性“date”賦值為“d”Bean,即該Bean的對(duì)象,故打印出了當(dāng)前時(shí)間。圖14.4控制臺(tái)輸出結(jié)果第44頁/共74頁14.2.5Bean的依賴關(guān)系從上例可以看出,Spring中是用“ref”來指定依賴關(guān)系的,用“ref”指定依賴關(guān)系有3中方法:local、bean和parent。前面的例子中應(yīng)用了“l(fā)ocal”方法指定,其實(shí)也可以應(yīng)用其他兩種方法,例如上例的配置文件若應(yīng)用“bean”可以修改為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="getDate"class="org.model.DateClass">

<propertyname="date"> <refbean="d"/> </property> </bean>

<beanid="d"class="java.util.Date"></bean></beans>第45頁/共74頁14.2.5Bean的依賴關(guān)系還可以直接應(yīng)用property中的ref屬性,例如上例可以修改為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="getDate"class="org.model.DateClass">

<propertyname="date"ref="d"></property> </bean>

<beanid="d"class="java.util.Date"></bean></beans>第46頁/共74頁14.2.6Bean的自動(dòng)裝配1.byName模式使用byName模式在Bean的初始化時(shí)會(huì)通過Bean的屬性名字進(jìn)行自動(dòng)裝配,在Spring的配置文件中,查找一個(gè)與將要裝配的屬性同樣名字的Bean。例如,DateClass.java為:

packageorg.model;importjava.util.Date;publicclassDateClass{ privateDatedate; publicDategetDate(){ returndate; } publicvoidsetDate(Datedate){ this.date=date; }}第47頁/共74頁14.2.6Bean的自動(dòng)裝配配置文件config.xml中可以用“byName”自動(dòng)裝配模式來為屬性“date”自動(dòng)裝配值,配置文件可以配置為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="getDate"class="org.model.DateClass"autowire="byName"> </bean> <beanid="date"class="java.util.Date"></bean></beans>第48頁/共74頁14.2.6Bean的自動(dòng)裝配可以發(fā)現(xiàn),在“getDate”Bean中沒有為屬性指定值,但指定了“autowire="byName"”。編輯測(cè)試類Test.java:

packageorg.test;importorg.model.DateClass;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.FileSystemXmlApplicationContext;publicclassTest{ publicstaticvoidmain(String[]args){ ApplicationContextac= newFileSystemXmlApplicationContext("/WebRoot/WEB-INF/classes/config.xml"); DateClassdc=(DateClass)ac.getBean("getDate"); System.out.println(dc.getDate()); }}

運(yùn)行后查看結(jié)果,輸出為:

WedJul2816:56:40CST2009第49頁/共74頁14.2.6Bean的自動(dòng)裝配2.使用byType模式byType模式指如果配置文件中正好有一個(gè)與屬性類型一樣的Bean,就自動(dòng)裝配這個(gè)屬性,如果有多于一個(gè)這樣的Bean,就拋出一個(gè)異常。例如在上例中,DateClass類的屬性date為“Date”類型,而在配置文件中也有一個(gè)“Date”類型的Bean,這時(shí)若配置了自動(dòng)裝配的byType模式,就會(huì)自動(dòng)裝配DateClass類中的屬性date值。例如,把上例的配置文件稍微修改,其他的不改變:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="getDate"class="org.model.DateClass"autowire="byType"> </bean> <beanid="date"class="java.util.Date"></bean></beans>第50頁/共74頁14.2.6Bean的自動(dòng)裝配3.使用constructor模式constructor模式指的是根據(jù)構(gòu)造方法的參數(shù)進(jìn)行自動(dòng)裝配。例如,把DateClass.java修改為:

packageorg.model;importjava.util.Date;publicclassDateClass{ privateDatedate;

publicDateClass(Datedate){ this.date=date; } publicDategetDate(){ returndate; } publicvoidsetDate(Datedate){ this.date=date; }}第51頁/共74頁14.2.6Bean的自動(dòng)裝配配置文件config.xml修改為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="getDate"class="org.model.DateClass"autowire="constructor"> </bean> <beanid="date"class="java.util.Date"></bean></beans>第52頁/共74頁14.2.6Bean的自動(dòng)裝配4.使用autodetect模式autodetect模式指的是通過檢查類的內(nèi)部來選擇使用constructor或byType模式。例如,把使用constructor模式的實(shí)例的配置文件修改為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="getDate"class="org.model.DateClass"autowire="autodetect"> </bean> <beanid="date"class="java.util.Date"></bean></beans>第53頁/共74頁14.2.6Bean的自動(dòng)裝配5.使用no模式使用no模式就是不使用自動(dòng)裝配,這時(shí)為屬性賦值就必須通過ref來引用其他Bean。例如,DateClass.java修改為:

packageorg.model;importjava.util.Date;publicclassDateClass{ privateDatedate; publicDateClass(Datedate){ this.date=date; } publicDategetDate(){ returndate; } publicvoidsetDate(Datedate){ this.date=date; }}第54頁/共74頁14.2.6Bean的自動(dòng)裝配配置文件修改為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="getDate"class="org.model.DateClass"autowire="no"> <propertyname="date"> <refbean="date"/> </property> </bean> <beanid="date"class="java.util.Date"></bean></beans>第55頁/共74頁14.3Bean中對(duì)集合的注入14.3.1對(duì)list的注入對(duì)list集合的注入非常簡(jiǎn)單,如果類中有l(wèi)ist類型的屬性,在為其依賴注入值的時(shí)候就需要在配置文件中的<property>元素下應(yīng)用其子元素<list>。下面舉例說明。創(chuàng)建類ListBean.java,其有一個(gè)List類型的屬性,代碼如下:

packageorg.model;importjava.util.List;publicclassListBean{ privateListlist; publicListgetList(){ returnlist; } publicvoidsetList(Listlist){ this.list=list; }}

第56頁/共74頁14.3.1對(duì)list的注入配置文件中Bean的配置為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="listBean"class="org.model.ListBean"> <propertyname="list">

<list> <value>java</value> <value>c++</value> <value>php</value> </list> </property> </bean></beans>第57頁/共74頁14.3.1對(duì)list的注入編寫測(cè)試類,對(duì)ListBean類的“l(fā)ist”屬性進(jìn)行輸入,測(cè)試是否注入成功。

packageorg.test;importjava.util.Iterator;importjava.util.List;importorg.model.ListBean;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.FileSystemXmlApplicationContext;publicclassTest{ publicstaticvoidmain(String[]args){ ApplicationContextac= newFileSystemXmlApplicationContext("/WebRoot/WEB-INF/classes/config.xml");

ListBeanlistbean=(ListBean)ac.getBean("listBean"); Listl=listbean.getList(); System.out.println(l); }}

運(yùn)行程序,控制臺(tái)信息為:

[java,c++,php]第58頁/共74頁14.3.2對(duì)Set的注入創(chuàng)建類SetBean.java,代碼編寫為:

packageorg.model;importjava.util.Set;publicclassSetBean{ privateSetset; publicSetgetSet(){ returnset; } publicvoidsetSet(Setset){ this.set=set; }}第59頁/共74頁14.3.2對(duì)Set的注入配置文件config.xml編寫為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="setbean"class="org.model.SetBean"> <propertyname="set">

<set> <value>java</value> <value>c++</value> <value>php</value> </set> </property> </bean></beans>

第60頁/共74頁14.3.2對(duì)Set的注入編寫測(cè)試類,代碼如下:

packagetest;importorg.model.SetBean;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.FileSystemXmlApplicationContext;publicclassTest{ publicstaticvoidmain(String[]args){ ApplicationContextac= newFileSystemXmlApplicationContext("/WebRoot/WEB-INF/classes/config.xml");

SetBeansetbean=(SetBean)ac.getBean("setbean"); System.out.println(setbean.getSet());

}}

運(yùn)行程序,輸出結(jié)果為:

[java,c++,php]

第61頁/共74頁14.3.3對(duì)Map的注入創(chuàng)建類MapBean.java,代碼編寫為:

packageorg.model;importjava.util.Map;publicclassMapBean{ privateMapmap; publicMapgetMap(){ returnmap; } publicvoidsetMap(Mapmap){ this.map=map; }}第62頁/共74頁14.3.3對(duì)Map的注入配置文件config.xml文件配置為:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.5.xsd"> <beanid="mapbean"class="org.model.MapBean"> <propertyname="map">

<map> <entrykey="java"> <value>JavaEE實(shí)用教程</value> </entry> <entrykey="c++"> <value>c++實(shí)用教程</value> </entry> <entrykey="php"> <value>PHP實(shí)用教程</value> </entry> </map> </property> </bean></beans>第63頁/共74頁14.3.3對(duì)Map的注入編寫測(cè)試類:

packageorg.test;importjava.util.Map;importorg.model.MapBean;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.FileSystemXmlApplicationContext;publicclassTest{ publicstaticvoidmain(String[]args){ ApplicationContextac= newFileSystemXmlApplicationContext("/WebRoot/WEB-INF/classes/config.xml"); MapBeanmapbean=(MapBean)ac.getBean("mapbean"); Mapmap=mapbean.getMap(); System.out.println(map); }}

運(yùn)行程序,控制臺(tái)輸出結(jié)果為:

{java=JavaEE實(shí)用教程,c++=c++實(shí)用教程,php=PHP實(shí)用教程}第64頁/共74頁14.4兩種后處理器14.4.1Bean后處理器下面舉例說明Bean后處理器的應(yīng)用。建立項(xiàng)目,添加Spring核心類庫后,在src下建立包“org.beanpost”,在該包下建立類MyBeanPost.java,代碼編寫如下:

packageorg.beanpost;importorg.springframework.beans.BeansException;importorg.springframework.beans.factory.config.BeanPostProcessor;publicclassMyBeanPostimplementsBeanPostProcessor{ publicObjectpostProcessAfterInitialization(Objectbean,Stringbeanname) throwsBeansException{ System.out.println("Bean后處理器在初始化之前對(duì)"+beanname+"進(jìn)行處理"); returnbean; } publicObjectpostProcessBeforeInitialization(Objectbean,Stringbeanname) throwsBeansException{ System.out.println("Bean后處理在初始化之后對(duì)"+beanname+"進(jìn)行處理"); returnbean; }}第

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論