《Java EE主流開源框架》第2部分 Spring框架_第1頁
《Java EE主流開源框架》第2部分 Spring框架_第2頁
《Java EE主流開源框架》第2部分 Spring框架_第3頁
《Java EE主流開源框架》第2部分 Spring框架_第4頁
《Java EE主流開源框架》第2部分 Spring框架_第5頁
已閱讀5頁,還剩235頁未讀 繼續(xù)免費閱讀

付費下載

下載本文檔

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

文檔簡介

Java主流開源框架Spring框架——導(dǎo)讀Spring框架是主流的JavaWeb開發(fā)框架,是一個輕量級的開源框架,具有很高的凝聚力和吸引力,在企業(yè)應(yīng)用開發(fā)中被廣泛使用。Spring框架由RodJohnson創(chuàng)立,在2004年發(fā)布了Spring框架的1.0正式版,其目的是用于降低企業(yè)應(yīng)用程序開發(fā)的難度和縮短開發(fā)周期。Spring框架不局限于服務(wù)器端的開發(fā)。從簡單性、可測試性和松耦合的角度看,任何Java應(yīng)用都可以從Spring框架中受益。Spring框架還是一個超級黏合平臺,除自己提供功能外,還具有黏合其他技術(shù)和框架的能力。本部分詳細介紹了Spring框架的多個知識點內(nèi)容,主要包括依賴注入DI、控制反轉(zhuǎn)IoC、面向切面編程AOP、

XML配置實現(xiàn)、注解實現(xiàn),以及Spring框架對Web層、數(shù)據(jù)訪問層的支持等內(nèi)容。并通過豐富的案例幫助讀者加深理解。通過學(xué)習(xí),讀者可以更好地知道Spring框架是什么、有什么優(yōu)點、怎么用等。2.1

Spring框架概述:Spring框架的創(chuàng)始人是Rod

Johnson,他曾是一位Java

EE技術(shù)專家,他在工作中發(fā)現(xiàn)Java

EE系統(tǒng)組件的一些弊端會使系統(tǒng)過于臃腫,于是出版了Expert

One-on-One?,J2EE

Design

and

Development(中文版譯名為《J2EE設(shè)計開發(fā)編程指南》)。他在該書中分析了Java

EE業(yè)務(wù)組件EJB(2.0版本)的種種弊端,提出了基于實用主義的業(yè)務(wù)層框架,并將其開源后在互聯(lián)網(wǎng)上發(fā)表,這就是后來的Spring框架。Spring框架可以被看成一個標(biāo)準(zhǔn)的開發(fā)組件,是一個輕量級的非入侵式框架,使用Spring框架開發(fā)的業(yè)務(wù)對象不需要依賴

Spring框架的API??梢园裇pring框架看成一個容器,它能夠管理業(yè)務(wù)對象的生命周期,是可以整合各種企業(yè)應(yīng)用的開源框架和優(yōu)秀的第三方類庫。讀者可以在Spring官方網(wǎng)站下載完整的類庫、源代碼及文檔,本書基于Spring

4.2版本組織學(xué)習(xí)內(nèi)容。第21章SJparvianEgE框W架eb快開速發(fā)入概門述2.2

Spring框架的體系結(jié)構(gòu):如圖2-1所示,Spring框架的模塊被劃分為五個層,每個層次解決不同的問題,下面對這五個層次進行簡單的介紹。1.Core

Container層Core

Container層(核心容器層)包括Beans模塊、Core模塊、Context模塊、SpEL模塊。Beans模塊和Core模塊是Spring框架的基礎(chǔ)部分,提供IoC(控制反轉(zhuǎn))和DI(依賴注入)功能,將在后續(xù)章節(jié)中詳細介紹。Context模塊構(gòu)建在Beans模塊和Core模塊的基礎(chǔ)上,提供類似于JNDI注冊器的框架式對象訪問方法;同時,Context模

塊也支持Java

EE的一些特性,例如EJB、JMX和基礎(chǔ)的遠程處理等。ApplicationContext接口是Context模塊的核心接口。SpEL模塊提供一種強大的表達式語言,用于在運行時查詢和操縱對象。第21章SJparvianEgE框W架eb快開速發(fā)入概門述2.1

Spring框架概述:2.AOP及Instrumentation層AOP及Instrumentation層包括AOP模塊、Aspects模塊、Instrumentation模塊、Messaging模塊。AOP(面向切面編程)模塊提供一個符合AOP聯(lián)盟標(biāo)準(zhǔn)的面向切面編程的實現(xiàn),是Spring框架除IoC外的另一個核心技術(shù),將在后續(xù)章節(jié)中詳細介紹。Aspects模塊提供對AspectJ的集成支持。Instrumentation模塊提供Class

Instrumentation支持及Classloader實現(xiàn),可以在特定的應(yīng)用服務(wù)器上使用框架。Messaging模塊為集成消息API和消息協(xié)議提供支持。第21章SJparvianEgE框W架eb快開速發(fā)入概門述2.1

Spring框架概述:3.Web層Web層包括WebSocket模塊、Servlet模塊、Web模塊、Portlet模塊。WebSocket模塊提供瀏覽器與服務(wù)端建立通信方式的支持。Servlet模塊包含Spring的MVC實現(xiàn),本書將詳細介紹Spring

MVC的使用。Web模塊提供基礎(chǔ)的面向Web的集成特性,例如多文件上傳、使用Servlet監(jiān)聽器初始化IoC容器及面向Web的應(yīng)用上下文等,還包含Spring遠程支持中的Web相關(guān)的功能。Portlet模塊提供用于Portlet環(huán)境和WebServlet模塊的MVC的實現(xiàn)。第21章SJparvianEgE框W架eb快開速發(fā)入概門述2.1

Spring框架概述:4.Data

Access/Integration層(數(shù)據(jù)訪問/集成層)Data

Access/Integration層(數(shù)據(jù)訪問/集成層)包括JDBC模塊、ORM模塊、OXM模塊、JMS模塊、Transactions模塊。JDBC模塊提供JDBC抽象層,簡化訪問數(shù)據(jù)庫的方式。ORM模塊為流行的ORM框架(例如JPA、JDO、Hibernate、MyBatis等)提供交互層,可以便捷地集成各種數(shù)據(jù)訪問層框架,本書將著重介紹MyBatis框架。OXM模塊提供一個Object/XML映射實現(xiàn)的抽象層。JMS(Java

Messaging

Service)模塊主要包含制造和消費消息的特性。Transaction(事務(wù))模塊支持編程和聲明性的事務(wù)處理。5.Test層Test層(測試層)支持在JUnit和TestNG下對Spring組件進行單元測試與集成測試。第21章SJparvianEgE框W架eb快開速發(fā)入概門述2.3核心概念—IoC:IoC(Inversion

of

Control)稱為控制反轉(zhuǎn),是Spring框架的核心基礎(chǔ),可以說Spring框架的一切功能都是基于IoC而來的,將在后續(xù)章節(jié)中詳細介紹,本節(jié)簡單介紹概念。在解釋什么是IoC之前,先從一個例子開始。任何一個應(yīng)用都是若干個對象互相協(xié)作完成的。創(chuàng)建一個對象后,總是需要對這個對象所依賴的屬性進行初始化。代碼如下所示:第21章SJparvianEgE框W架eb快開速發(fā)入概門述public

class

A{private

B

b;public

void

setB(B

b){

this.b=b;}}public

class

B{private

C

c;public

void

setC(C

c){

this.c=c;}}public

class

C{}上述代碼中共有三個類,分別是A類、B類和C類。其中,A類實例總是依賴一個B類實例,而B類實例總是依賴一個C類實例。因此,想正常使用A類實例,需要如下所示的創(chuàng)建裝配的過程:C

c=new

C();B

b=new

B();b.setC(c);A

a=new

A();a.setB(b);2.3核心概念—IoC:上篇代碼中通過創(chuàng)建C類實例,把C類實例注入給B類實例,再將B類實例注入給A類實例,最終構(gòu)建出一個可用的A類實例。在實際應(yīng)用中,類似這樣的代碼隨處可見,A類實例越復(fù)雜,則對其裝配的過程越復(fù)雜。如果裝配關(guān)系有所變化,則需要修改源代碼。如果使用Spring框架構(gòu)建應(yīng)用,則對實例之間的裝配關(guān)系不再需要自行編寫代碼控制,可以交給IoC容器來實現(xiàn),容器通過解析XML配置文件或者注解即可正確裝配,這就是所謂的“控制反轉(zhuǎn)”,即控制權(quán)由應(yīng)用代碼中轉(zhuǎn)到了外部容器,控制權(quán)

的轉(zhuǎn)移就是反轉(zhuǎn)。從另外的角度出發(fā),IoC也被稱為DI(Dependency

Injection,依賴注入)。依賴注入非常直觀地描述了這一特征,即應(yīng)用程序依賴IoC容器注入需要的實例等資源。可以說,IoC和DI是本質(zhì)相同的概念,區(qū)別是角度不同,IoC從容器的角度出發(fā),而DI從應(yīng)用程序的角度出發(fā)。第21章SJparvianEgE框W架eb快開速發(fā)入概門述2.4核心概念—AOP:在企業(yè)應(yīng)用中,很多模塊可能需要實現(xiàn)相同的功能,如多個模塊都需要日志功能、權(quán)限校驗功能、事務(wù)處理功能等,這些相同的功能就被稱為“切面”。AOP(Aspect

Oriented

Program,面向切面編程)能夠?qū)⑼ㄓ玫墓δ芘c業(yè)務(wù)模塊分離,是OOP(Object

OrientedProgram,面向?qū)ο缶幊蹋┑难永m(xù)和補充。AOP并不是Spring框架提出的技術(shù),早在1997年就由Gregor

Kiczales領(lǐng)導(dǎo)的

研究小組提出。目前,已有上百種項目宣稱能支持AOP,Spring框架是眾多支持AOP項目中的一個。例如,在一個應(yīng)用中有用戶管理、訂單管理、支付等功能模塊,每個模塊都需要記錄日志,那么就可以把日志看作一個切面單獨進行開發(fā),然后使用Spring框架的AOP支持編程,能降減少碼冗余,提高工作效率。同時,如果日志功能需要改變,不需要修改其他功能模塊的源代碼,只要單獨更新日志相關(guān)代碼即可,大大提高了程序的可擴展性。第21章SJparvianEgE框W架eb快開速發(fā)入概門述2.4核心概念—AOP:單獨開發(fā)日志功能后,可以使用AOP編程將日志功能“織入”各個功能模塊中,“織入”的過程不需要修改功能模塊的源代碼,只通過XML配置文件或注解即可完成。第21章SJparvianEgE框W架eb快開速發(fā)入概門述3.1

BeanFactory與ApplicationContext:上一章提到,IoC是Spring框架的核心技術(shù),也是框架所有功能的基礎(chǔ)。Spring框架實現(xiàn)了IoC容器,能夠根據(jù)配置文件或注解為應(yīng)用程序生成對象,并管理這些對象的生命周期,這些對象被稱為bean。容器生成bean后,應(yīng)用程序需要能夠訪問這些bean進而實現(xiàn)應(yīng)用功能。Spring

IoC容器的代表是API中的BeanFactory接口。IoC容器裝配成功的bean都可以通過BeanFactory獲得,進而在應(yīng)用中使用。BeanFactory中提供的getBean方法可以獲得bean對象,如Object

getBean(String

name)方法,其中參數(shù)

name為配置文件中bean的id值,返回值是IoC容器裝配成功的bean對象。BeanFactroy采用延遲加載形式注入bean,即只有在使用某個bean(調(diào)用getBean()方法)時,才對該bean進行加載實例化。BeanFactory有很多子接口,在Java

EE應(yīng)用中,建議使用其子接口ApplicationContext來替代BeanFactory,因為

ApplicationContext擴展了BeanFactory,不僅能實現(xiàn)BeanFactory所有功能,還擴展了一些企業(yè)應(yīng)用中的特性。

ApplicationContext是接口,不能直接創(chuàng)建對象,可以使用其實現(xiàn)類創(chuàng)建對象,如ClassPathXmlApplicationContext、FileSystemXmlApplicationContext等。Application

Context與BeanFactory相反,它會在容器啟動時,一次性創(chuàng)建所有的bean,即在容器啟動時,就可以發(fā)現(xiàn)Spring框架中存在的配置錯誤。第31章SJparvianEgE核W心eb組開件發(fā)概述第31章SJparvianEgE核W心eb組開件發(fā)概述3.1

BeanFactory與ApplicationContext:例如,在ApplicationContext.xml中配置了bean后(在后續(xù)章節(jié)中介紹如何配置),通過如下代碼使用bean:public

static

void

main(String[]

args)

{ApplicationContext

ctxt=

new

ClassPathXmlApplicationContext("applicationContext.xml");BasicDataSource

dataSource

=

(BasicDataSource)

txt.getBean("dataSource");Connection

conn=null;for(int

i=0;i<15;i++){try

{conn=dataSource.getConnection();System.out.println("connection

"+i+"

:

"+conn.hashCode());}

catch

(SQLException

e)

{e.printStackTrace();}}}在上述代碼中,首先創(chuàng)建了ClassPathXmlApplicationContext對象,該對象依據(jù)配置文件ApplicationContext.xml獲得

IoC容器的信息。3.1

BeanFactory與ApplicationContext:使用ClassPathXmlApplicationContext中的getBean方法獲得id為dataSource的bean對象。接下來就可以通過獲得的bean對象來獲得連接,使用數(shù)據(jù)庫連接池??梢?,使用IoC容器裝配對象后,在源代碼中不需要再進行煩瑣的編程,可以便捷地使用ApplicationContext中定義的getBean方法獲得bean進行使用,對象完全交給容器管理。在了解了如何使用容器管理的bean后,下一節(jié)將學(xué)習(xí)如何定義bean的基本配置信息,以便IoC容器能夠根據(jù)配置信息生成應(yīng)用程序需要的bean。第31章SJparvianEgE核W心eb組開件發(fā)概述3.2

Spring

bean的基本配置:Spring框架的IoC容器所管理的對象稱為bean,bean的元數(shù)據(jù)(基礎(chǔ)信息)可以在XML中進行配置。除XML外,還有其他方式可以定義bean的元數(shù)據(jù),包括使用Java屬性文件、自定義編程等,目前XML配置bean還是最常用的方式。習(xí)慣上,bean的XML配置文件名字為ApplicationContext.xml,也可以任意命名為其他名字。配置文件中至少配置一個<bean></bean>,但是往往會有多個<bean>,都配置在<beans>下,配置文件模板如下所示:第31章SJparvianEgE核W心eb組開件發(fā)概述<?xml

version="1.0"

encoding="UTF-8"?><beans

xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.

org/schema/aop"xsi:schemaLocation="/schema/beans

/schema/beans/spring-beans-4.0.xsd

/schema/aop

/schema/aop/spring-aop-4.0.xsd"><bean

id="

"

class="

"></bean></beans>3.2

Spring

bean的基本配置:在<beans></beans>標(biāo)簽中配置多個<bean></bean>,配置bean時,必須指定的是id和class屬性,其中id是該bean的唯一標(biāo)記,上一節(jié)學(xué)習(xí)到的ApplicationContext可以使用getBean方法通過id值獲取具體的bean對象進行使用。class屬性定義該bean的類型,既可以是具體類,也可以是接口。每個bean基本都有不同的屬性,需要為屬性賦值,為屬性賦值的具體方式有多種,將在第4章中詳細介紹,此處演示最簡單的賦值方法,代碼如下所示:第31章SJparvianEgE核W心eb組開件發(fā)概述<bean

id="dataSource"

class="mons.dbcp.BasicDataSource"><property

name="driverClassName"><value>com.mysql.jdbc.Driver</value></property><property

name="url"><value>jdbc:mysql://localhost:3306/test</value></property><property

name="username"><value>root</value></property><property

name="password"><value>1234</value></property><property

name="maxActive"><value>10</value></property><property

name="initialSize"><value>2</value></property></bean>BasicDataSource

dataSource

=

new

BasicDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/test");dataSource.setUsername("root");dataSource.setPassword("1234");dataSource.setMaxActive(10);dataSource.setInitialSize(2);3.2

Spring

bean的基本配置:使用Spring框架后,就不再需要煩瑣的Java編程來裝配對象,只要直接從容器中獲取使用即可,代碼如下所示:第31章SJparvianEgE核W心eb組開件發(fā)概述public

static

void

main(String[]

args)

{ApplicationContext

ctxt

=

new

ClassPathXmlApplicationContext("applicationContext.xml");BasicDataSource

dataSource

=

(BasicDataSource)

txt.getBean("dataSource");}上述代碼使用Spring框架的IoC容器來生成bean,并使用getBean方法獲取對象。試想一下,如果dataSource對象的屬性有變化,使用IoC容器只需要修改XML文件即可,dataSource對象就可以使用新的屬性。否則,就需要修改每處創(chuàng)建

dataSource對象的源代碼,才能保證修改成功??梢?,使用Spring框架的IoC容器生成并管理bean對象,能提高應(yīng)用程序的可擴展性及代碼復(fù)用性。3.3

bean的作用域:使用XML配置bean的元數(shù)據(jù),<bean></bean>節(jié)點描述了一個實例的基本特征,包括其類型、屬性值等,如同一個實例的模板,根據(jù)這個模板,IoC容器就可以為應(yīng)用程序創(chuàng)建出具體的bean實例。<bean>節(jié)點可以通過scope屬性定義bean的作用域,scope的屬性值有四個,如表3-1所示。第31章SJparvianEgE核W心eb組開件發(fā)概述屬性值含義singleton永遠使用一個唯一的bean對象,是scope的默認(rèn)值prototype每次使用都構(gòu)建一個新的bean對象request每次HTTP請求構(gòu)建一個bean實例(在Web環(huán)境中生效)session在一個HTTP

Session中,永遠使用一個唯一的bean實例(在Web環(huán)境中生效)3.3

bean的作用域:使用導(dǎo)引案例中的SalaryInfo類說明不同的作用域。在ApplicationContext.xml中配置兩個bean,代碼如下所示:在上述配置文件中,配置了兩個bean,id為sInfo1的bean沒有使用scope屬性,則默認(rèn)為singleton,id為sInfo2的bean使用scope屬性,賦值為prototype。第31章SJparvianEgE核W心eb組開件發(fā)概述<bean

id="sInfo1"

class="com.chinasofti.salary.vo.SalaryInfo"><property

name="id"><value>1</value></property><property

name="basicSalary"><value>5000</value></property><property

name="meritPay"><value>2000</value></property><property

name="basis"><value>5000</value></property></bean><bean

id="sInfo2"

class="com.chinasofti.salary.vo.SalaryInfo"

scope="prototype"><property

name="id"><value>1</value></property><property

name="basicSalary"><value>5000</value></property><property

name="meritPay"><value>2000</value></property><property

name="basis"><value>5000</value></property></bean>3.3

bean的作用域:使用如下代碼測試:在上述代碼中,分別獲得兩個sInfo1實例,使用雙等號判斷引用是否相等。如果相等,則表示是同一個實例;如果不相等,則表示是兩個實例。運行結(jié)果如下所示:第31章SJparvianEgE核W心eb組開件發(fā)概述public

static

void

main(String[]

args)

{ApplicationContext

ctxt=new

ClassPathXmlApplicationContext("scope.xml");SalaryInfo

s1=(SalaryInfo)

ctxt.getBean("sInfo1");SalaryInfos2=(SalaryInfo)ctxt.getBean("sInfo1");SalaryInfos3=(SalaryInfo)ctxt.getBean("sInfo2");SalaryInfo

s4=(SalaryInfo)

ctxt.getBean("sInfo2");System.out.println("s1==s2:

"+(s1==s2));System.out.println("s3==s4:

"+(s3==s4));}s1==s2:

trues3==s4:

false3.3

bean的作用域:可見,兩個id為sInfo1的bean實例是同一個實例,因為默認(rèn)是singleton作用域,所以表示單例,永遠返回同一個實例。而

sInfo2的兩個實例是不同的實例,因為scope是prototype,表示每次都返回一個新的實例。除了默認(rèn)的singleton和prototype,還有request和session兩個屬性,需要在Web環(huán)境中測試使用,request表示在一個請求中使用同一個實例,session表示在一個會話中使用同一個實例。如果除了Spring框架預(yù)定義的四個作用域,還需要其他作用域,則可以通過實現(xiàn)org.springframework.beans.factory.config.Scope自定義作用域類。第31章SJparvianEgE核W心eb組開件發(fā)概述3.4實例化bean的方法:通過上一節(jié)的示例可見,使用IoC容器管理bean,主要包括實例化bean及裝配bean兩個方面。在裝配bean之前,需要能夠?qū)嵗痓ean。只要在XML中定義好bean的元數(shù)據(jù),調(diào)用ApplicationContext的getBean方法就可以使用裝配好的實例。在使用實例之前,該實例肯定已經(jīng)被實例化。本節(jié)學(xué)習(xí)如何在XML文件中指定IoC容器實例化bean對象的不同方法。上述內(nèi)容以SalaryInfo類為例,展示不同的實例化方法。值得注意的是,在實際應(yīng)用中,SalaryInfo這樣的實體類往往不會使用IoC容器進行管理,而DAO類、Service服務(wù)類等會使用IoC容器進行管理。IoC容器通常有以下三種實例化bean的方法。第31章SJparvianEgE核W心eb組開件發(fā)概述3.4實例化bean的方法:1.通過無參構(gòu)造方法實例化在配置文件中,如果只使用id和class屬性配置bean,則默認(rèn)調(diào)用類的無參構(gòu)造方法實例化。如下配置將調(diào)用SalaryInfo類的無參構(gòu)造方法創(chuàng)建實例。代碼如下所示:第31章SJparvianEgE核W心eb組開件發(fā)概述<bean

id="sInfo"

class="com.chinasofti.salary.vo.SalaryInfo"

scope="prototype"></bean>在配置文件中可以使用factory-method屬性調(diào)用該靜態(tài)工廠方法并創(chuàng)建實例。當(dāng)使用sInfo3時,則調(diào)用SalaryInfo類中的

createSalaryInfo方法返回實例。代碼如下所示:第31章SJparvianEgE核W心eb組開件發(fā)概述3.4實例化bean的方法:2.通過靜態(tài)工廠方法實例化有些類中提供了靜態(tài)的工廠方法返回實例,假設(shè)SalaryInfo類中有如下靜態(tài)工廠方法:public

static

SalaryInfo

createSalaryInfo(){System.out.println("invoke

createSalaryInfo()");return

new

SalaryInfo();}<bean

id="sInfo3"

class="com.chinasofti.salary.vo.SalaryInfo"

factory-method="createSalaryInfo"></bean>第31章SJparvianEgE核W心eb組開件發(fā)概述3.4實例化bean的方法:3.通過非靜態(tài)工廠方法實例化有些類中可能使用非靜態(tài)工廠方法返回實例,假設(shè)存在一個類SalaryInfoFactory,其中提供了非靜態(tài)的工廠方法以返回實例,代碼如下所示:public

class

SalaryInfoFactory

{public

SalaryInfo

createSalaryInfo(){System.out.println("invoke

SalaryInfoFactory

createSalaryInfo()");return

new

SalaryInfo();}}在上述工廠類中,定義了非靜態(tài)的工廠方法createSalaryInfo,返回實例SalaryInfo,接下來可以在XML中配置使用。<bean

id="factorybean"

class="com.chinasofti.test.SalaryInfoFactory"

></bean><bean

id="sInfo4"

factory-bean="factorybean"

factory-method="createSalaryInfo"></bean>3.4實例化bean的方法:上篇配置文件中,首先實例化了工廠類SalaryInfoFactory的實例factorybean,然后配置id為sInfo4的bean時,通過

factory-bean指定使用該工廠bean,并通過factory-method指定使用工廠方法createSalaryInfo實例化SalaryInfo的實例。當(dāng)應(yīng)用程序規(guī)模較大時,往往需要配置很多bean,那么可以根據(jù)邏輯相關(guān)配置到不同的XML文件中。例如本章示例中,使用到兩個XML,分別是ApplicationContext.xml和Scope.xml文件,可以通過字符串?dāng)?shù)組傳遞參數(shù),生成一個上下文對象,代碼如下所示:如上代碼所示,context對象可以獲取兩個XML文件中配置的bean。除此之外,也可以把多個XML文件引入一個XML文件中,代碼如下所示:第31章SJparvianEgE核W心eb組開件發(fā)概述ApplicationContext

context

=

new

ClassPathXmlApplicationContext(new

String[]{"scope.xml",

"applicationContext.

xml"});<import

resource="applicaitonContext.xml"/><bean

id="sInfo1"

class="com.chinasofti.salary.vo.SalaryInfo">…在上述配置文件中,引入了ApplicationContext.xml,等同于形成一個XML文件,值得注意的是,<import>必須在所有<bean>定義之前使用。3.5第一個Spring框架實例:1.創(chuàng)建Java工程,引入Spring框架的核心包Spring框架可以在任何類型的工程中使用,使用Eclipse開發(fā)平臺創(chuàng)建Java工程,右鍵單擊工程名稱,選擇“屬性”→

“build

path”→“l(fā)ibraries”→“Add

External

Jars”菜單命令,添加Spring框架的核心jar包(從官網(wǎng)下載Spring框架相關(guān)資源),Spring框架的jar包很多,目前用到的功能很少,所以只引入核心jar包即可第31章SJparvianEgE核W心eb組開件發(fā)概述3.5第一個Spring框架實例:2.創(chuàng)建案例中使用的Java類案例模擬操作系統(tǒng)可以自由選擇不同的USB設(shè)備進行數(shù)據(jù)存儲,先定義抽象類USBStorage,描述USB設(shè)備的基本特征,代碼如下所示:第31章SJparvianEgE核W心eb組開件發(fā)概述public

abstract

class

USBStorage

{private

String

volumeLabel;public

String

getVolumeLabel()

{return

volumeLabel;}public

void

setVolumeLabel(String

volumeLabel)

{this.volumeLabel

=

volumeLabel;}public

abstract

void

writeData();}3.5第一個Spring框架實例:在上述抽象類USBStorage中定義了抽象方法writeData,需要在子類中實現(xiàn)。假設(shè)有U盤及移動硬盤兩種USB設(shè)備,則定義兩個子類,代碼如下所示:在上述代碼中定義了兩個子類,分別描述U盤及移動硬盤,各自實現(xiàn)了不同的寫數(shù)據(jù)方法。第31章SJparvianEgE核W心eb組開件發(fā)概述public

class

UDisk

extends

USBStorage

{public

void

writeData()

{System.out.println("向U盤中寫入數(shù)據(jù)……");}}public

class

PortableHD

extends

USBStorage

{public

void

writeData()

{System.out.println("向移動硬盤中寫入數(shù)據(jù)……");}}3.5第一個Spring框架實例:接下來定義操作系統(tǒng)類,操作系統(tǒng)會識別不同的移動設(shè)備,進行寫數(shù)據(jù)操作,代碼如下所示:第31章SJparvianEgE核W心eb組開件發(fā)概述public

class

OperationSystem

{USBStorage

storage;public

USBStorage

getStorage()

{return

storage;}public

void

setStorage(USBStorage

storage)

{this.storage

=

storage;}public

void

saveFile()

{System.out.println(storage.getVolumeLabel());storage.writeData();}}在上述代碼中,OperationSystem類關(guān)聯(lián)了抽象類USBStorage,可以根據(jù)需要,動態(tài)為USBStorage賦值為UDisk或PortableHD。3.5第一個Spring框架實例:3.在XML文件中定義beanOperationSystem實例總要使用一個USBStorage才能進行寫文件操作,需要使用Spring框架的IoC容器來實例化并裝配

OperationSystem類型的bean,在src目錄下創(chuàng)建并編寫firstdemo.xml文件,代碼如下所示:在上述配置文件中,定義了UDisk類型的bean,id為udisk;定義了PortableHD類型的bean,id為protableHD;定義了類型為OperationSystem的bean,該bean需要一個屬性storage,storage在類中定義的類型是抽象類型USBStorage,所以該抽象類的任意子類類型都可以賦值給storage。在上述配置文件中把udisk賦值給storage,也就是目前使用U盤作為移動存儲設(shè)備。第31章SJparvianEgE核W心eb組開件發(fā)概述<bean

id="udisk"

class="com.chinasofti.firstdemo.UDisk"><property

name="volumeLabel"value="Jerry的U盤"/></bean><bean

id="portableHD"

class="com.chinasofti.firstdemo.PortableHD"><property

name="volumeLabel"value="Jerry的移動硬盤"/></bean><bean

id="os"

class="com.chinasofti.firstdemo.OperationSystem"><property

name="storage"

ref="udisk"></property></bean>3.5第一個Spring框架實例:4.測試使用定義Computer類,模擬進行存文件操作,代碼如下所示:在上述代碼中,使用id為os的bean,調(diào)用saveFile方法。由于os的storage使用了udisk,所以將使用UDisk類的方法存文件,運行結(jié)果如下所示:第31章SJparvianEgE核W心eb組開件發(fā)概述public

class

Computer

{public

static

void

main(String[]

args)

{ApplicationContext

ctx

=

new

ClassPathXmlApplicationContext("firstdemo.xml");OperationSystem

os

=

(OperationSystem)

ctx.getBean("os");os.saveFile();}}Jerry的U盤向U盤中寫入數(shù)據(jù)……3.5第一個Spring框架實例:5.修改裝配關(guān)系,再次測試假設(shè)目前需要使用移動硬盤進行存儲,那么只修改firstdemo.xml中對os的配置即可,代碼如下所示:在上述配置文件中,修改了os的裝配關(guān)系,將移動硬盤ProtableHD實例賦值給storage屬性。再次運行Computer類,運行結(jié)果如下所示:第31章SJparvianEgE核W心eb組開件發(fā)概述<bean

id="udisk"

class="com.chinasofti.firstdemo.UDisk"><property

name="volumeLabel"value="Jerry的U盤"/></bean><bean

id="portableHD"

class="com.chinasofti.firstdemo.PortableHD"><property

name="volumeLabel"value="Jerry的移動硬盤"/></bean><bean

id="os"

class="com.chinasofti.firstdemo.OperationSystem"><property

name="storage"

ref="portableHD"></property></bean>Jerry的移動硬盤向移動硬盤中寫入數(shù)據(jù)……3.5第一個Spring框架實例:假設(shè)需要增加一種新的移動存儲類,只要創(chuàng)建新類,繼承抽象父類USBStorage,實現(xiàn)抽象方法,然后在XML中配置bean,賦值給OperationSystem的storage屬性即可。對已有的源代碼不需要做任何修改,就可以使用新的存儲設(shè)備類。可見,使用Spring框架進行編程,把重要的實例都交給IoC容器生成并管理,能夠提高應(yīng)用的可擴展性。第31章SJparvianEgE核W心eb組開件發(fā)概述4.1依賴注入方式:Spring框架的IoC容器實現(xiàn)的核心功能是實例化bean并為bean的屬性進行賦值,同時對bean的生命周期等進行管理,也就是為bean注入其需要的資源。在前面章節(jié)的示例代碼中,沒有深入學(xué)習(xí)注入方式,本節(jié)將詳細學(xué)習(xí)Spring框架的依賴注入方式。依賴注入方式分為手動裝配及自動裝配兩大類:手動裝配需要明確指明每個屬性的值;自動裝配可以選擇不同的策略,交代給IoC容器自動為bean尋找合適的屬性值進行裝配。自動裝配雖然聽起來非常便捷,但是存在一定的局限性,在自動查找的過程中,如果存在有歧義的屬性,則會發(fā)生錯誤,對此將在后續(xù)章節(jié)中詳細介紹。第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)4.1依賴注入方式:如下所示的XML配置為手動裝配方式:在上述XML文件中,使用手動裝配方式配置service,指定了屬性dao的值是前面配置好的id為dao的bean。第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)<bean

id="dao"

class="com.chinasofti.salary.dao.EmployeeDAOJDBCImpl"></bean><bean

id="service"

class="com.chinasofti.salary.service.EmployeeServiceImpl"><property

name="dao"><ref

bean="dao"/></property></bean>4.1依賴注入方式:對于同樣的service,可以使用如下方式自動裝配:在上述XML文件中,使用autowire="byName"聲明service使用通過名字自動裝配的方式,自動將id為dao的bean裝配給

service。自動裝配需要IoC容器自行查找匹配的值進行裝配,因此當(dāng)bean較多時,容易出現(xiàn)混淆的情況。第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)<bean

id="dao"

class="com.chinasofti.salary.dao.EmployeeDAOJDBCImpl"></bean><bean

id="service"

class="com.chinasofti.salary.service.EmployeeServiceImpl"autowire="byName"></bean>4.1.1手動裝配:在一個Java類中,有兩種方法可以為一個實例的屬性進行賦值,即setter方法和構(gòu)造方法。Spring框架的IoC容器也通過調(diào)用這兩種方法為bean的屬性賦值。下面使用SalaryInfo類說明兩種方法的基本使用,代碼如下所示:第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)public

class

SalaryInfo

{private

int

id;private

double

basicSalary;private

double

meritPay;private

double

basis;get、set、構(gòu)造省略在上述代碼中,SalaryInfo類定義了四個屬性,均為基本數(shù)據(jù)類型及String類型,并定義了無參構(gòu)造方法及setter方法。4.1.1手動裝配:第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)(1)setter方法注入。setter方法注入指的是調(diào)用類中的setXXX方法為屬性賦值,其中XXX為屬性名字。在<bean></bean>標(biāo)簽中,使用<property></property>進行裝配時,IoC容器則調(diào)用類的setter方法進行賦值。例如<property

name="basicSalary"><value>10000</value></property>,將調(diào)用類中的setBasicSalary方法,將10000作為形式參數(shù)傳入,進行賦值<bean

id="sInfo"

class="com.chinasofti.salary.vo.SalaryInfo"><property

name="id"><value>1</value></property><property

name="basicSalary"><value>10000</value></property><property

name="meritPay"><value>5000</value></property><property

name="basis"><value>8000</value></property></bean>在上述配置中,對SalaryInfo類型的bean,使用<property></property>進行裝配,即調(diào)用對應(yīng)的setter方法,將value值傳入賦值,如果沒有對應(yīng)的setter方法,則發(fā)生錯誤。值得一提的是,此處演示的類屬性類型均為基本數(shù)據(jù)類型或String類型,為其指定具體值時使用<value></value>即可。然而,在實際應(yīng)用開發(fā)過程中,很多屬性的類型往往不僅是基本數(shù)

據(jù)類型和String類型,還可能是其他的引用類型、集合,甚至null等。當(dāng)屬性類型是其他類型時,就不再使用<valule></value>,而是使用其他標(biāo)簽進行裝配,對此將在后續(xù)章節(jié)中介紹。4.1.1手動裝配:第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)(2)構(gòu)造方法注入。構(gòu)造方法注入指的是調(diào)用類中有參數(shù)的構(gòu)造方法注入,例如SalaryInfo類中存在如下帶參構(gòu)造方法:public

SalaryInfo(int

id,

double

basicSalary,

double

meritPay,

double

basis)

{super();this.id

=

id;this.basicSalary

=

basicSalary;this.meritPay

=

meritPay;this.basis

=

basis;}使用<constructor-arg></constructor-arg>標(biāo)簽替代<property></property>進行裝配,IoC容器將調(diào)用構(gòu)造方法進行注入。<bean

id="sInfo2"

class="com.chinasofti.salary.vo.SalaryInfo"><constructor-arg

type="int"><value>1</value></constructor-arg><constructor-arg

type="double"><value>10000</value></constructor-arg><constructor-arg

type="double"><value>5000</value></constructor-arg><constructor-arg

type="double"><value>8000</value></constructor-arg></bean>4.1.1手動裝配:在上述XML文件中,使用<constructor-arg></constructor-arg>注入bean,構(gòu)造方法有多個參數(shù),根據(jù)指定參數(shù)類型type的值,IoC容器會調(diào)用匹配的構(gòu)造方法進行賦值。在上述配置中,IoC容器會調(diào)用構(gòu)造方法SalaryInfo(int,double,double,double)進行賦值。另外,也可以指定構(gòu)造方法參數(shù)的索引值來進行注入,索引值從0開始,代碼如下所示:第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)<bean

id="sInfo3"

class="com.chinasofti.salary.vo.SalaryInfo"><constructor-arg

index="0"><value>1</value></constructor-arg><constructor-arg

index="1"><value>8000</value></constructor-arg><constructor-arg

index="2"><value>3000</value></constructor-arg><constructor-arg

index="3"><value>8000</value></constructor-arg></bean>在上述XML文件中,使用索引值指定構(gòu)造方法的參數(shù)順序進行賦值。值得一提的是,由于一個類可能存在多個構(gòu)造方法,所以使用構(gòu)造方法賦值時可能存在歧義,不如setter方法明確,因此建議使用setter方法。第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)4.1.2自動裝配:自動裝配(autowire)可以使XML文件更為精簡。例如,導(dǎo)引案例中的service需要關(guān)聯(lián)dao,也就是使用service實例必須為其裝配一個dao實例,dao實現(xiàn)類代碼如下所示:public

class

EmployeeDAOJDBCImpl

implements

EmployeeDAO

{@Overridepublic

Employee

selectByNamePwd(String

loginName,

String

empPwd)

{//省略其他代碼……service實現(xiàn)類代碼如下所示:public

class

EmployeeServiceImpl

implements

EmployeeService

{//關(guān)聯(lián)dao對象private

EmployeeDAO

dao;//無參構(gòu)造方法public

EmployeeServiceImpl()

{super();}//創(chuàng)建service對象時,為dao對象賦值public

EmployeeServiceImpl(EmployeeDAO

dao)

{this.dao

=

dao;}//setter方法public

void

setDao(EmployeeDAO

dao)

{this.dao

=

dao;}4.1.2自動裝配:service實現(xiàn)類關(guān)聯(lián)dao對象,名字為dao,類型為EmployeeDAO。在使用service實例前,必須為其屬性dao賦值。除使

用上一節(jié)中的<property>及<constructor-arg>調(diào)用setter方法和構(gòu)造方法進行手動裝配外,還可以使用自動裝配。自動裝配有兩種常用的方式,即通過類型的byType方式和通過名字的byName方式。(1)byType方式自動裝配。byType方式自動裝配指的是根據(jù)屬性類型自動檢測裝配,代碼如下所示:在上述XML文件中,使用byType方式自動裝配service,IoC容器將查找service對應(yīng)類EmployeeServiceImpl中的setter方法,找到public

void

setDao(EmployeeDAO

dao)方法,其參數(shù)類型是EmployeeDAO,則接下來在XML中查找類型為EmployeeDAO的bean,找到一個id為dao的bean,類型是EmployeeDAOJDBCImpl。由于EmployeeDAOJDBCImpl是EmployeeDAO的子類,所以dao是EmployeeDAO類型的bean,IoC容器就自動將dao注入service使用。如果XML中有多個類型是EmployeeDAO的bean,則會報錯。第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)<bean

id="dao"

class="com.chinasofti.salary.dao.EmployeeDAOJDBCImpl"></bean><bean

id="service"

class="com.chinasofti.salary.service.EmployeeServiceImpl"

autowire="byType"></bean>4.1.2自動裝配:(2)byName方式自動裝配。byName方式自動裝配指的是根據(jù)屬性名字自動檢測裝配,代碼如下所示:在上述XML文件中,對id為service的bean聲明了autowire="byName",IoC容器將檢測EmployeeServiceImpl中的setter方法,找到public

void

setDao(EmployeeDAO

dao)方法。因為方法名是setDao,所以IoC容器認(rèn)為屬性名字是dao,則到XML中查找名字是dao的bean,找到后裝配給service,完成byName方式的自動裝配。第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)<bean

id="dao"

class="com.chinasofti.salary.dao.EmployeeDAOJDBCImpl"></bean><bean

id="service"

class="com.chinasofti.salary.service.EmployeeServiceImpl"

autowire="byName"></bean>4.2不同類型的屬性裝配:在上面章節(jié)中,指定具體屬性值的時候,使用的示例代碼中的屬性類型都是基本數(shù)據(jù)類型或String類型。在實際應(yīng)用中,屬性類型可以多種多樣,可以歸納為基本數(shù)據(jù)類型和String類型、其他的bean類型、集合類型、null。本節(jié)學(xué)習(xí)每種類型的不同配置方法。(1)基本數(shù)據(jù)類型和String類型?;緮?shù)據(jù)類型和String類型在上面章節(jié)中已經(jīng)多次使用,使用<value></value>直接賦值即可,不再贅述。第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)4.2不同類型的屬性裝配:(2)其他bean類型。如果bean的屬性不是基本數(shù)據(jù)類型或String類型,而是其他的bean,則不能使用<value></value>配置,而采用另外兩種配置方式,分別為外部bean和內(nèi)部bean。依然以上述的EmployeeDAO及EmployeeService為例,使用手動裝配方式來裝配service。service需要一個EmployeeDAO類型的屬性,在XML中已經(jīng)定義了一個類型為EmployeeDAO的bean,所以可以把這個bean注入service。代碼如下所示:<bean

id="dao"

class="com.chinasofti.salary.dao.EmployeeDAOJDBCImpl"></bean><bean

id="service"

class="com.chinasofti.salary.service.EmployeeServiceImpl"><property

name="dao"><ref

bean="dao"/></property></bean>在上述XML中,使用<ref

bean="dao"/>為service注入屬性,使用到已經(jīng)定義好的id為dao的bean,這樣的bean稱為外部bean。注入外部bean還有一個等價的方式,代碼如下所示:<bean

id="dao"

class="com.chinasofti.salary.dao.EmployeeDAOJDBCImpl"></bean><bean

id="service"

class="com.chinasofti.salary.service.EmployeeServiceImpl"><property

name="dao"

ref="dao"></property></bean>4.2不同類型的屬性裝配:兩種方式完全等價,都是將一個已經(jīng)定義好的bean注入另一個bean中,這種外部bean可以被注入多個bean中。如果某個

bean不會被多個bean使用,則可以聲明為內(nèi)部bean,代碼如下所示:在上述XML中,使用內(nèi)部bean注入service的屬性dao,比起外部bean,內(nèi)部bean只能在當(dāng)前的bean中使用,不能被其他

bean引用。第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)<bean

id="service"

class="com.chinasofti.salary.service.EmployeeServiceImpl"><property

name="dao"><bean

class="com.chinasofti.salary.dao.EmployeeDAOJDBCImpl"></bean></property></bean>4.2不同類型的屬性裝配:(3)集合類型。在實際應(yīng)用中,類和類之間可能是一對多的關(guān)聯(lián)關(guān)系,那么就需要使用集合類型來持有“多”的一方的對象。例如,存在

Order類和Item類,Order類中關(guān)聯(lián)多個Item實例,因此使用List集合來實現(xiàn)這樣的一對多關(guān)聯(lián)關(guān)系,代碼如下所示:當(dāng)類的屬性是集合類型時,也可以使用IoC容器進行注入。常用的集合類型有四種,即List、Set、Map及Properties,本節(jié)將分別介紹這四種集合類型的配置方式。第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)public

class

Order

{private

String

id;

private

Customer

customer;private

List<Item>

items;//省略其他代碼……4.2不同類型的屬性裝配:①<list>。如果屬性是List或數(shù)組類型,IoC容器將使用<list>元素進行配置。<list>元素中的子元素可以根據(jù)該List或數(shù)組對象中存儲的元素類型進行選擇,可以是<value>、<ref>、<null>、<list>等。代碼如下所示:第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)<bean

id="item1"

class="com.chinasofti.cart.Item"><property

name="itemid"><value>1</value></property><property

name="name"><null/></property><property

name="price"><value>34.5</value></property></bean><bean

id="item2"

class="com.chinasofti.cart.Item"><property

name="itemid"><value>2</value></property><property

name="name"><value>DVD</value></property><property

name="price"><value>23</value></property></bean><bean

id="cart"

class="com.chinasofti.cart.Order"><property

name="id"><value>1</value></property><property

name="customer"><ref

bean="customer"/></property><property

name="items"><list><ref

bean="item1"/><ref

bean="item2"/></list></property></bean>使用<list>元素將item1和item2添加到集合items中,賦值給屬性items。4.2不同類型的屬性裝配:②<set>。當(dāng)集合采用Set類型的集合類時,則采用<set>元素進行裝配,用法與<list>相同。③<map>。當(dāng)集合采用Map類型的映射類時,則采用<map>元素進行裝配。代碼及語法結(jié)構(gòu)如下所示:第41章SJparvianEgE框W架eb的開I發(fā)oC概容述器實現(xiàn)<bean><property

name=""><map><entry><key><value></value></key><ref/></entry></map></property></bean><map>元素下可以有多對<entry></entry>條目元素,每個條目配置Map的一對鍵值對。其中<key>用來配置當(dāng)前條目

的鍵值,<key>元素內(nèi)可以使用<value>、<ref>、<list>和<set>等各種類型元素,在上述示例中使用<value>。鍵值對中的值也

溫馨提示

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

評論

0/150

提交評論