眾所周知,Web這個(gè)Intemet上最熱門(mén)的應(yīng)用架構(gòu)是由Tim Bemers-Lee發(fā)明的。Web的前身是1980年Tim Bemers-Lee負(fù)責(zé)的Enquire(Enquire Within Upon Everything的簡(jiǎn)稱)項(xiàng)目。1990年11月,第一個(gè)web服務(wù)器nxoc01.eem.ch開(kāi)始運(yùn)行,Tim Bemers-Lee在自己編寫(xiě)的圖形化web瀏覽器Worldwideweb上看到了最早的Web頁(yè)面。1991年,CERN(European Particle Physies Laboratory)正式發(fā)布了Web技術(shù)標(biāo)準(zhǔn)。目前,與web相關(guān)的各種技術(shù)標(biāo)準(zhǔn)都由著名的W3C組織(World Wide Web Consortium)管理和維護(hù)。
Web是一種典型的分布式應(yīng)用架構(gòu)。Web應(yīng)用中的每一次信息交換都要涉及到客戶端和服務(wù)端兩個(gè)層面。因此,Web開(kāi)發(fā)技術(shù)大體上也可以被分為客戶端技術(shù)和服務(wù)端技術(shù)兩大類(lèi)。
Web客戶端的主要任務(wù)是展現(xiàn)信息內(nèi)容,而HTML語(yǔ)言則是信息展現(xiàn)的最有效載體之一。作為一種實(shí)用的超文本語(yǔ)言,HTML的歷史最早可以追溯到上世紀(jì)四十年代。1945年,Vannevar Bush在一篇文章中闡述了文本和文本之間通過(guò)超級(jí)鏈接相互關(guān)聯(lián)的思想,并在文中給出了一種能實(shí)現(xiàn)信息關(guān)聯(lián)的計(jì)算機(jī)Mcmex的設(shè)計(jì)方案。Doug Engelbart等人則在1960年前后,對(duì)信息關(guān)聯(lián)技術(shù)做了最早的實(shí)驗(yàn)。與此同時(shí),Ted Nelson正式將這種信息關(guān)聯(lián)技術(shù)命名為超文本(Hypertext)技術(shù)。1969年,IBM的Charles Goldfarb由發(fā)明了可用于描述超文本信息的GML(Generalized Markup Language)語(yǔ)言。1978到1986年間,在ANSI等組織的努力下,GML語(yǔ)言進(jìn)一步發(fā)展成為著名的SGML語(yǔ)言標(biāo)準(zhǔn)。當(dāng)Tim Bemers-Lee和他的同事們?cè)?989年試圖創(chuàng)建一個(gè)基于超文本的分布式應(yīng)用系統(tǒng)時(shí),Tim Bemers-Lee意識(shí)到,SGML是描述超文本信息的一個(gè)上佳方案,但美中不足的是,SGML過(guò)于復(fù)雜,不利于信息的傳遞和解析。于是,Tim Bemers-Lee對(duì)SGML語(yǔ)言做了大刀闊斧的簡(jiǎn)化和完善。1990年,第一個(gè)圖形化的Web瀏覽器“World Wide Web”終于可以使用一種為Web量身定制的語(yǔ)言HTML來(lái)展現(xiàn)超文本信息了。
最初的HTML語(yǔ)言只能在瀏覽器中展現(xiàn)靜態(tài)的文本或圖像信息,這滿足不了人們對(duì)信息豐富性和多樣性的強(qiáng)烈需求,最終,由靜態(tài)技術(shù)向動(dòng)態(tài)技術(shù)的轉(zhuǎn)變成為了Web客戶端技術(shù)演進(jìn)的永恒定律。
1995年Java語(yǔ)言的問(wèn)世為Web客戶端帶來(lái)了巨大的變革。Java語(yǔ)言天生就具備的平臺(tái)無(wú)關(guān)的特點(diǎn),讓人們一下子找到了在瀏覽器中開(kāi)發(fā)動(dòng)態(tài)應(yīng)用的捷徑。而后來(lái)CSS與DHTML技術(shù)的加入,讓HTML頁(yè)面真正做到了動(dòng)感無(wú)限。
與客戶端技術(shù)從靜態(tài)向動(dòng)態(tài)的演進(jìn)過(guò)程類(lèi)似,Web服務(wù)端的開(kāi)發(fā)技術(shù)也是由靜態(tài)向動(dòng)態(tài)逐漸發(fā)展、完善起來(lái)的。最早的Web服務(wù)器簡(jiǎn)單地響應(yīng)瀏覽器發(fā)來(lái)的HTTP請(qǐng)求,并將存儲(chǔ)在服務(wù)器上的HTML文件返回給瀏覽器。一種名為SSI(Server Side Ineludes)的技術(shù)可以讓W(xué)eb服務(wù)器在返回HTML文件前,更新HTML文件的某些內(nèi)容,但其功能非常有限。第一種真正使服務(wù)器能根據(jù)運(yùn)行時(shí)的具體情況,動(dòng)態(tài)生成HTML頁(yè)面的是CGI(Common Gateway Interface)技術(shù),它使客戶端和服務(wù)端的動(dòng)態(tài)信息交換成為了可能。隨著CGI技術(shù)的普及,聊天室、論壇、電子商務(wù)、信息查詢、全文檢索等各式各樣的Web應(yīng)用蓬勃興起,人們終于可以享受到信息檢索、信息交換、信息處理等更為便捷的信息服務(wù)了。
1994年,Rasmus Lerdorf發(fā)明了專用于Web服務(wù)端編程的PHP(Personal Home Page Tools)語(yǔ)言。Web應(yīng)用的開(kāi)發(fā)者可以用一種更加簡(jiǎn)便、快捷的方式實(shí)現(xiàn)動(dòng)態(tài)Web功能。1996年,Microsoft借鑒PHP的思想,在其Web服務(wù)器IIS3.0中引入了ASP技術(shù)。當(dāng)然,以Sun公司為首的Java陣營(yíng)也不會(huì)示弱。1997年,Servlet技術(shù)問(wèn)世,1998年,JSP技術(shù)誕生。Servlet和JSP的組合(還可以加上JavaBean技術(shù))讓Java開(kāi)發(fā)者同時(shí)擁有了類(lèi)似CGI程序的集中處理功能和類(lèi)似PHP的HTML嵌入功能,此外,Java的運(yùn)行時(shí)編譯技術(shù)也大大提高了Servlet和JSP的執(zhí)行效率,這也正是Servlet和JsP被后來(lái)的J2EE平臺(tái)吸納為核心技術(shù)的原因之一。
Web服務(wù)端開(kāi)發(fā)技術(shù)的完善使開(kāi)發(fā)復(fù)雜的Web應(yīng)用成為了可能。在此起彼伏的電子商務(wù)大潮中,為了適應(yīng)企業(yè)級(jí)應(yīng)用開(kāi)發(fā)的各種復(fù)雜需求,為了給最終用戶提供更可靠、更完善的信息服務(wù),兩個(gè)最重要的企業(yè)級(jí)開(kāi)發(fā)平臺(tái)J2EE和.NET在2000年前后分別誕生于Java和Windows陣營(yíng),它們隨即就在企業(yè)級(jí)Web開(kāi)發(fā)領(lǐng)域展開(kāi)競(jìng)爭(zhēng)。
J2EE是純粹基于Java的解決方案。1998年,Sun發(fā)布了EJB1.0標(biāo)準(zhǔn)。EJB為企業(yè)級(jí)應(yīng)用中必不可少的數(shù)據(jù)封裝、事務(wù)處理、交易控制等功能提供了良好的技術(shù)基礎(chǔ)。至此,J2EE平臺(tái)的三大核心技術(shù)servlet、JSP和EJB都已先后問(wèn)世。1999年,Sun正式發(fā)布了J2EE的第一個(gè)版本。緊接著,遵循J2EE標(biāo)準(zhǔn),為企業(yè)級(jí)應(yīng)用提供支撐平臺(tái)的各類(lèi)應(yīng)用服務(wù)軟件爭(zhēng)先恐后地涌現(xiàn)了出來(lái)。IBM的websphere、BEA的WebLogic都是這一領(lǐng)域里最為成功的商業(yè)軟件平臺(tái)。隨著開(kāi)源運(yùn)動(dòng)的興起,JBoSS、Tomcat等開(kāi)源世界里的應(yīng)用服務(wù)新秀也吸引了許多用戶的注意力。到目前,Sun的J2EE 5已經(jīng)發(fā)布,其中三個(gè)關(guān)鍵組件的版本也演進(jìn)到了Servlet2.5、JSP2.1和EJB3.0。至此,J2EE體系及相關(guān)的軟件產(chǎn)品已經(jīng)成為了web服務(wù)端開(kāi)發(fā)的一個(gè)強(qiáng)有力的支撐環(huán)境。
2000年以后,隨著Web應(yīng)用的日益復(fù)雜,人們逐漸意識(shí)到,單純依靠某種技術(shù)多半無(wú)法達(dá)到快速開(kāi)發(fā)、快速驗(yàn)證和快速部署的最佳境界。研究者開(kāi)始嘗試著將已有的Web開(kāi)發(fā)技術(shù)綜合起來(lái),形成完整的開(kāi)發(fā)框架或應(yīng)用模型,并以此來(lái)滿足各種復(fù)雜的應(yīng)用需求。目前,在J2EE多層架構(gòu)上己經(jīng)開(kāi)發(fā)出了很多框架,它們?yōu)閼?yīng)用開(kāi)發(fā)提供了一個(gè)能夠使用的架構(gòu)模板和軟件包,讓開(kāi)發(fā)者從編碼中解脫出來(lái),不必一切從頭開(kāi)始,自己來(lái)完成,只需將注意力集中在業(yè)務(wù)邏輯上,從而減輕了開(kāi)發(fā)者處理復(fù)雜問(wèn)題的負(fù)擔(dān),提高了工作效率。其次在應(yīng)用和分析框架的基礎(chǔ)上,可以對(duì)其進(jìn)行改進(jìn)和擴(kuò)展,以適應(yīng)實(shí)際的需求。
WebWork
Webwork是由Open Symphony組織開(kāi)發(fā)的,致力于組件化和代碼重用的拉出式MVC模式J2EE Web框架。現(xiàn)在的Webwork2.x前身是Rickard Oberg開(kāi)發(fā)的Webwork,但現(xiàn)在Webwbrk已經(jīng)被拆分成了Xwork1和Webwork2兩個(gè)項(xiàng)目。XWork簡(jiǎn)潔、靈活功能強(qiáng)大,它是一個(gè)標(biāo)準(zhǔn)的Command模式實(shí)現(xiàn),并且完全從web層脫離出來(lái)。
Struts
Struts是一個(gè)基于Sun J2EE平臺(tái)的MVC框架,主要是采用Servlet和JSP技術(shù)來(lái)實(shí)現(xiàn)的。由于Struts能充分滿足應(yīng)用開(kāi)發(fā)的需求,簡(jiǎn)單易用,敏捷迅速,在過(guò)去的一年中頗受關(guān)注。Struts把Servlet、JSP、自定義標(biāo)簽和信息資源(message resources)整合到一個(gè)統(tǒng)一的框架中,開(kāi)發(fā)人員利用其進(jìn)行開(kāi)發(fā)時(shí)不用再自己編碼實(shí)現(xiàn)全套MVC模式,有效的縮短了開(kāi)發(fā)周期。
TaPestry
Tapestry是一個(gè)開(kāi)源的基于servlet的應(yīng)用程序框架,它使用組件對(duì)象模型來(lái)創(chuàng)建動(dòng)態(tài)的,交互的Web應(yīng)用。一個(gè)組件就是任意一個(gè)帶有jwcid屬性的html標(biāo)記。其中jwc的意思是Java Web Component。TaPestry使得java代碼與html完全分離,利用這個(gè)框架開(kāi)發(fā)大型應(yīng)用變得輕而易舉。并且開(kāi)發(fā)的應(yīng)用容易維護(hù)和升級(jí)。
IBAIS
使用ihatis提供的ORM機(jī)制,對(duì)業(yè)務(wù)邏輯實(shí)現(xiàn)人員而言,面對(duì)的是純粹的Java對(duì)象,這一層與通過(guò)Hibemate實(shí)現(xiàn)ORM而言基本一致,而對(duì)于具體的數(shù)據(jù)操作,Hibernate會(huì)自動(dòng)生成SQL語(yǔ)句,而ibatis則要求開(kāi)發(fā)者編寫(xiě)具體的SQL語(yǔ)句。
Hibemate
Hibemate是Java平臺(tái)上的一種全功能的、開(kāi)放源代碼OR映射框架。Hibemate在許多方面類(lèi)似于EJB(容器管理的持久性/容器管理的關(guān)系)和JDO(Java Data Objeets)。與JDO不同,Hibemate完全著眼于關(guān)系數(shù)據(jù)庫(kù)的OR映射,并且包括比大多數(shù)商業(yè)產(chǎn)品更多的功能。Hibernate使用反射和運(yùn)行時(shí)字節(jié)碼生成,使它對(duì)于最終用戶幾乎是透明的。Hibenate已經(jīng)成為輕量級(jí)J2EE項(xiàng)目中持久層框架的首選,使用Hibemate可以在輕量級(jí)J2EE架構(gòu)中取代CMP,完成數(shù)據(jù)持久化的重任。
Spring
Spring是一個(gè)解決了許多在J2EE開(kāi)發(fā)中常見(jiàn)的問(wèn)題的強(qiáng)大框架。Spring提供了管理業(yè)務(wù)對(duì)象的一致方法并且鼓勵(lì)了注入對(duì)接口編程而不是對(duì)類(lèi)編程的良好習(xí)慣。Spring的架構(gòu)基礎(chǔ)是基于使用JavaBean屬性的Inversion of Controf容器。然而,這僅僅是完整圖景中的一部分:Spring在使用IOC容器作為構(gòu)建所有架構(gòu)層的完整解決方案方面是獨(dú)一無(wú)二的。Spring提供了唯一的數(shù)據(jù)訪問(wèn)抽象,包括簡(jiǎn)單和有效率的JDBC框架,極大的改進(jìn)了效率并且減少了可能的錯(cuò)誤。Spring的數(shù)據(jù)訪問(wèn)架構(gòu)還集成了Hibemate和其他O/R
mapping解決方案。Spring還提供了唯一的事務(wù)管理抽象,它能夠在各種底層事務(wù)管理技術(shù),例如JTA或者JDBC事務(wù)提供一個(gè)一致的編程模型。Spring提供了一個(gè)用標(biāo)準(zhǔn)Java語(yǔ)言編寫(xiě)的AOP框架,它給POJOs提供了聲明式的事務(wù)管理和其他企業(yè)事務(wù)。Spring框架的使用,使得應(yīng)用程序能夠拋開(kāi)EJB的復(fù)雜性,同時(shí)享受著和傳統(tǒng)EJB相關(guān)的關(guān)鍵服務(wù)。Spring還提供了可以和IOC容器集成的強(qiáng)大而靈活的MVC Web框架。
2.1 ASSH框架的技術(shù)基礎(chǔ)
2.1.1 J2EE架構(gòu)
J2EE(Java2 Entenprise Edition)是sun公司主持推出的一項(xiàng)企業(yè)計(jì)算平臺(tái)規(guī)范,它是一種利用Java2平臺(tái)來(lái)簡(jiǎn)化企業(yè)解決方案的開(kāi)發(fā)、部署和管理相關(guān)的復(fù)雜問(wèn)題的體系結(jié)構(gòu)。J2EE技術(shù)的基礎(chǔ)就是核心Java平臺(tái)或Java2平臺(tái)的標(biāo)準(zhǔn)版,J2EE不僅鞏固了標(biāo)準(zhǔn)版中的許多優(yōu)點(diǎn),例如“編寫(xiě)一次、隨處運(yùn)行”的特性、方便存取數(shù)據(jù)庫(kù)的 JDBC API、CORBA技術(shù)以及能夠在Internet應(yīng)用中保護(hù)數(shù)據(jù)的安全模式等等,同時(shí)還提供了對(duì)EJB(Enierprise JavaBeans)、 Java Servlets API、 JSP(Java Server Pages)以及XML技術(shù)的全面支持。其最終目的就是成為一個(gè)能夠使企業(yè)開(kāi)發(fā)者大幅縮短投放市場(chǎng)時(shí)間的體系結(jié)構(gòu)。
SUN設(shè)計(jì)J2EE的初衷正是為了解決C/S模式 (client/server)的弊端,在傳統(tǒng)模式中,客戶端擔(dān)當(dāng)了過(guò)多的角色而顯得臃腫,在這種模式中,第一次部署的時(shí)候比較容易,但難于升級(jí)或改進(jìn),可伸展性也不理想。它使得重用業(yè)務(wù)邏輯和界面邏輯非常困難。J2EE使用多層的分布式應(yīng)用模型,應(yīng)用邏輯按功能劃分為組件,各個(gè)應(yīng)用組件根據(jù)他們所在的層分布在不同的機(jī)器上。這種模型將兩層化模型中的不同層面切分成許多層。一個(gè)多層化應(yīng)用能夠?yàn)椴煌拿糠N服務(wù)提供一個(gè)獨(dú)立的層。
J2EE的三層體系結(jié)構(gòu),即表現(xiàn)層、業(yè)務(wù)邏輯層和數(shù)據(jù)持久層。表現(xiàn)層主要指用戶界面,它要求盡可能的簡(jiǎn)單,使最終用戶不需要進(jìn)行任何培訓(xùn)就能方便地訪問(wèn)信息;第二層是業(yè)務(wù)邏輯層,也就是常說(shuō)的中間件,所有的應(yīng)用系統(tǒng)、應(yīng)用邏輯、控制都在這一層,系統(tǒng)的復(fù)雜性也主要體現(xiàn)在業(yè)務(wù)邏輯層;最后的數(shù)據(jù)持久層存儲(chǔ)大量的數(shù)據(jù)信息和數(shù)據(jù)邏輯,所有與數(shù)據(jù)有關(guān)的安全、完整性控制、數(shù)據(jù)的一致性、并發(fā)操作等都是在第三層完成。
采用J2EE三層結(jié)構(gòu)的特點(diǎn):
1.能有效降低建設(shè)和維護(hù)成本,簡(jiǎn)化管理。
2.適應(yīng)大規(guī)模和復(fù)雜的應(yīng)用需求。
3.可適應(yīng)不斷的變化和新的業(yè)務(wù)需求。
4.訪問(wèn)異構(gòu)數(shù)據(jù)庫(kù)。
5.能有效提高系統(tǒng)并發(fā)處理能力。
6.能有效提高系統(tǒng)安全性。
2.1.2StrutS框架
1.StrutS體系結(jié)構(gòu)
StrutS是Apache基金會(huì)Jakarta項(xiàng)目組的一個(gè)開(kāi)源項(xiàng)目,它采用MVC模式,提供了對(duì)開(kāi)發(fā)MVC系統(tǒng)的底層支持,能夠很好地幫助java開(kāi)發(fā)者利用J2EE開(kāi)發(fā)Web應(yīng)用。和其他的java架構(gòu)一樣,Struts也是面向?qū)ο笤O(shè)計(jì),將MVC模式“分離顯示邏輯和業(yè)務(wù)邏輯”的能力發(fā)揮得淋漓盡致。它采用的主要技術(shù)是Servlet,JSP和Custom tag library。其基本構(gòu)成如圖2一1所示:

由上圖可以看出,在Struts框架中Controller功能由ActionServlet和ActionMapping對(duì)象構(gòu)成,核心是一個(gè)Servlet類(lèi)型的對(duì)象ActionServlet,它用來(lái)接受客戶端的請(qǐng)求。ActionServlet包括一組基于配置的ActionMapping對(duì)象,每個(gè)ActionMapping對(duì)象實(shí)現(xiàn)了一個(gè)請(qǐng)求到一個(gè)具體的Model部分中Action處理器對(duì)象之間的映射。
Model部分由Action和Acti。nForm對(duì)象構(gòu)成。所有的Action處理器對(duì)象都是開(kāi)發(fā)者從Struts的Action類(lèi)派生的子類(lèi)。Action處理器對(duì)象封裝了具體的處理邏輯,調(diào)用業(yè)務(wù)邏輯模塊,并且把響應(yīng)提交到合適的View組件以產(chǎn)生響應(yīng)。Struts提供的ActionForm組件對(duì)象可以通過(guò)定義屬性描述客戶端表單數(shù)據(jù)。開(kāi)發(fā)者可以從它派生子類(lèi)對(duì)象,利用它和Struts提供的自定義標(biāo)記庫(kù)結(jié)合可以實(shí)現(xiàn)對(duì)客戶端的表單數(shù)據(jù)的良好封裝和支持,Action處理器對(duì)象可以直接對(duì)它進(jìn)行讀寫(xiě),而不再需要和request、response對(duì)象進(jìn)行數(shù)
據(jù)交互。通過(guò)ActionForm組件對(duì)象實(shí)現(xiàn)了對(duì)View和Model之間交互的支持。View部分是通過(guò)JSP技術(shù)實(shí)現(xiàn)的。Struts提供了自定義的標(biāo)一記庫(kù),通過(guò)這些自定義標(biāo)記可以非常好地和系統(tǒng)的Model部分交互,通過(guò)使用這些自定義標(biāo)一記創(chuàng)建的JSP表單,可以實(shí)現(xiàn)和Model部分中的ActionForm的映射,完成對(duì)用戶數(shù)據(jù)的封裝。
Struts框架在應(yīng)用中采用兩個(gè)基于XML的配置文件來(lái)進(jìn)行配置,分別是web.xml和struts-config.xml文件。web.xml文件是配置所有web應(yīng)用的,而struts-config.xml文件是Struts框架的部署描述符,用來(lái)創(chuàng)建和配置各種Struts組件。
2.Struts工作流程
在Web啟動(dòng)時(shí)加載并初始化AetionServlet。AetionServlet從struts-config.xml文件中讀取配置信息,把它們存放到各種配置對(duì)象中。初始化完成后,系統(tǒng)將通過(guò)URL匹配映射截獲所有以.do結(jié)尾的URL請(qǐng)求。當(dāng)ActionServlet接收到一個(gè)客戶請(qǐng)求時(shí):
(1)判斷用戶請(qǐng)求是否為Struts受理范圍的請(qǐng)求,如果是則接受請(qǐng)求。
(2)檢索和用戶請(qǐng)求匹配的ActionMapping實(shí)例,如果不存在,就返回用戶請(qǐng)求路徑無(wú)效。
(3)如果ActionForm實(shí)例不存在,就創(chuàng)建一個(gè)ActionForm對(duì)象,把客戶提交表單數(shù)據(jù)保存到ActionForm對(duì)象中。
(4)根據(jù)配置決定是否需要表單驗(yàn)證,如果需要驗(yàn)證,就調(diào)用ActionForm的validate()方法。
(5)如果AetionForm的validate()方法返回null或返回一個(gè)不包含ActionMessage的AetionError對(duì)象,就表示表單驗(yàn)證成功。
(6)ActionServlet根據(jù)AetionMapping實(shí)例包含的映射決定將請(qǐng)求轉(zhuǎn)發(fā)給哪個(gè)Action。如果相應(yīng)的Action實(shí)例不存在,就先創(chuàng)建這個(gè)實(shí)例,然后調(diào)用Aetion的execute()方法。
(7)Aetion的execute()方法返回一個(gè)AetionForward對(duì)象,ActionServlet再把客戶請(qǐng)求轉(zhuǎn)發(fā)給ActionForward對(duì)象指向的JSP組件。
(8)ActionForward對(duì)象指向的JSP組件生成動(dòng)態(tài)網(wǎng)頁(yè),返回給客戶。
對(duì)于以上流程(5)中,如果ActionForm的validate()方法返回一個(gè)包含一個(gè)或多個(gè)ActionMessage的ACtionErrors對(duì)象,就表示表單驗(yàn)證失敗,此時(shí)ActionServlet將直接把請(qǐng)求轉(zhuǎn)發(fā)給包含用戶提交表單的JSP組件。在這種情況下,不會(huì)再創(chuàng)建Action對(duì)象并調(diào)用Action的execute()方法。
StrutS工作流程圖如圖2一2所示:

2.1.3 Spring框架
Spring是J2EE平臺(tái)上的一個(gè)開(kāi)源應(yīng)用框架。Spring框架本身并沒(méi)有強(qiáng)制實(shí)行任何特別的編程模式。在Java社區(qū)里,Spring作為EJB模型之外的另外一個(gè)選擇甚至是替代品而廣為流行。從設(shè)計(jì)上看,Spring給予了Java程序員許多的自由度,但同時(shí)對(duì)業(yè)界常見(jiàn)的問(wèn)題也提供了良好的文檔和易于使用的方法。
1.Spring框架的組成模塊
Spring框架是一個(gè)分層架構(gòu),由7個(gè)定義良好的模塊組成。Spring模塊構(gòu)建在核心容器之上,核心容器定義了創(chuàng)建、配置和管理bean的方式,如圖2-3所示。

組成Spring框架的每個(gè)模塊(或組件)都可以單獨(dú)存在,或者與其他一個(gè)或多個(gè)模塊聯(lián)合實(shí)現(xiàn)。每個(gè)模塊的功能可見(jiàn)附錄一。
附錄一
核心容器:核心容器提供Spring框架的基本功能。核心容器的主要組件是BeanFactory,它是工廠模式的實(shí)現(xiàn)。BeanFactory使用控制反轉(zhuǎn)(IOC)模式將應(yīng)用程序的配置和依賴性規(guī)范與實(shí)際的應(yīng)用程序代碼分開(kāi)。
Spring上下文:Spring上下文是一個(gè)配置文件,向Spring框架提供上下文信息。Spring上下文包括企業(yè)服務(wù),例如JNDI、EJB、電子郵件、國(guó)際化、校驗(yàn)和調(diào)度功能。
SpringAOP:通過(guò)配置管理特性,SpringAOP模塊直接將面向方面的編程功能集成到了Spring框架中。所以,可以很容易地使Spring框架管理的任何對(duì)象支持AOP。SpringAOP模塊為基于Spring的應(yīng)用程序中的對(duì)象提供了事務(wù)管理服務(wù)。
SpringDAO:JDBC DAO抽象層提供了有意義的異常層次結(jié)構(gòu),可用該結(jié)構(gòu)來(lái)管理異常處理和不同數(shù)據(jù)庫(kù)供應(yīng)商拋出的錯(cuò)誤消息。異常層次結(jié)構(gòu)簡(jiǎn)化了錯(cuò)誤處理,并且極大地降低了需要編寫(xiě)的異常代碼數(shù)量(例如打開(kāi)和關(guān)閉連接)。Spring DAO的面向JDBC的異常遵從通用的DAO異常層次結(jié)構(gòu)。
SpringORM:Spring框架插入了若干個(gè)ORM框架,從而提供了ORM的對(duì)象關(guān)系工具,其中包括JDO、Hibernate和iBatiSSQLMap。所有這些都遵從Spring的通用事務(wù)和DAO異常層次結(jié)構(gòu)。
Spring Web模塊:web上下文模塊建立在應(yīng)用程序上下文模塊之上,為基于Web的應(yīng)用程序提供了上下文。所以,Spring框架支持與Jakarta Struts的集成。Web模塊還簡(jiǎn)化了處理多部分請(qǐng)求以及將請(qǐng)求參數(shù)綁定到域?qū)ο蟮墓ぷ鳌?br />
SpringMVC框架:MVC框架是一個(gè)全功能的構(gòu)建Web應(yīng)用程序的MVC實(shí)現(xiàn)。通過(guò)策略接口,MVC框架變成為高度可配置的,MVC容納了大量視圖技術(shù),其中包括JSP、veloeity、Tiles、iText和POI。
2. Spring框架的相關(guān)技術(shù)
(1)控制反轉(zhuǎn)(Ioc)與依賴注入(DI)
控制反轉(zhuǎn)模式(Inversion of Control)簡(jiǎn)稱IOC,其原理是基于好萊塢原則:別找我們,我們會(huì)找你。也就是說(shuō),所有的組件都是被動(dòng)的,所有的組件初始化和調(diào)用都由容器負(fù)責(zé)。控制反轉(zhuǎn)意味著在系統(tǒng)開(kāi)發(fā)過(guò)程中,設(shè)計(jì)的類(lèi)將交由容器去控制,而不是在類(lèi)的內(nèi)部去控制,類(lèi)與類(lèi)之間的關(guān)系將交由容器處理,這與傳統(tǒng)的編程方式有了很大的不同。Martin Fowler在他的一篇文章中給IOC起了一個(gè)更為直觀的名字:依賴注射DI(Dependency Injection),即組件之間的依賴關(guān)系由容器在運(yùn)行期決定,形象地說(shuō),即由容器動(dòng)態(tài)地將某種依賴關(guān)系注入到組件之中。
使用Spring框架管理J2EE應(yīng)用各層的對(duì)象時(shí),不管是控制層的Action對(duì)象,還是業(yè)務(wù)層的Service對(duì)象,還是持久層的DAO對(duì)象,都可在Spring的管理下有機(jī)地協(xié)調(diào)、運(yùn)行。Spring將各層的對(duì)象以松耦合的方式組織在一起,Action對(duì)象無(wú)須關(guān)心Service對(duì)象的具體實(shí)現(xiàn),Service對(duì)象無(wú)須關(guān)心持久層對(duì)象的具體實(shí)現(xiàn),各層對(duì)象的調(diào)用完全面向接口。當(dāng)系統(tǒng)需要重構(gòu)時(shí),代碼的改寫(xiě)量將大大減少。而這一切都得益于Spring的核心機(jī)制IOC,它讓Spring框架中Bean與Bean之間以配置文件組織在一起,而不是以硬編碼的方式耦合在一起。
Spring框架中的三種注入方式,分別為:
①接口注入
②設(shè)值注入
③構(gòu)造子注入
(2)面向方面編程(AOP)
Spring框架的另一優(yōu)勢(shì)是它的面向方面編程技術(shù),相對(duì)于面向?qū)ο缶幊潭裕嫦蚍矫婢幊烫峁牧硪粋€(gè)角度來(lái)考慮程序結(jié)構(gòu)以完善面向?qū)ο缶幊?OOP),為開(kāi)發(fā)者提供了一種描述橫切關(guān)注點(diǎn)的機(jī)制,并能夠自動(dòng)將橫切關(guān)注點(diǎn)織入到面向?qū)ο蟮能浖到y(tǒng)中,從而實(shí)現(xiàn)了橫切關(guān)注點(diǎn)的模塊化lll]。通過(guò)劃分Aspect代碼,橫切關(guān)注點(diǎn)變得容易處理。開(kāi)發(fā)者可以在編譯時(shí)更改、插入或除去系統(tǒng)的Aspect,甚至重用系統(tǒng)的Aspect。
Spring AOP用純Java實(shí)現(xiàn)。它不需要專門(mén)的編譯過(guò)程。Spring AOP不需要控制類(lèi)裝載器層次,因此它適用于J2EE Web容器或應(yīng)用服務(wù)器。
Spring實(shí)現(xiàn)AOP的方法跟其他的框架不同。Spring并不是要嘗試提供最完整的AOP實(shí)現(xiàn)(盡管Spring AOP有這個(gè)能力),相反的,它其實(shí)側(cè)重于提供一種AOP實(shí)現(xiàn)和Spring IOC容器的整合,用于幫助解決在企業(yè)級(jí)開(kāi)發(fā)中的常見(jiàn)問(wèn)題。
因此,Spring AOP通常都和Spring IOC容器一起使用。Aspect使用普通的bean定義語(yǔ)法(盡管Spring提供了強(qiáng)大的“自動(dòng)代理(autoproxying)”功能):與其他AOP實(shí)現(xiàn)相比這是一個(gè)顯著的區(qū)別。有些是使用Spring AOP無(wú)法輕松或者高效的完成的,如通知一個(gè)細(xì)粒度的對(duì)象,這種時(shí)候,使用Aspect是最好的選擇。不過(guò)經(jīng)驗(yàn)告訴我們:大多數(shù)在J2EE應(yīng)用中遇到的問(wèn)題,只要適合AOP來(lái)解決的,Spring AOP都沒(méi)有問(wèn)題,SpringAOP提供了一個(gè)非常好的解決方案。
2.1.4 Hibernate框架
Hibernate框架作為對(duì)象/關(guān)系映射(Object/Relational Mapping)的解決方案,就是將Java中的對(duì)象與對(duì)象關(guān)系映射至關(guān)系型數(shù)據(jù)庫(kù)中的表格與表格之間的關(guān)系。Hibernate內(nèi)部封裝了通過(guò)JDBC訪問(wèn)數(shù)據(jù)庫(kù)的操作,向上層應(yīng)用提供了面向?qū)ο蟮臄?shù)據(jù)訪問(wèn)API,使得Java程序員可以隨心所欲的使用對(duì)象編程思想來(lái)操縱數(shù)據(jù)庫(kù)。
Hibernate是一種非強(qiáng)迫性的解決方案。開(kāi)發(fā)者在寫(xiě)業(yè)務(wù)邏輯與持續(xù)性類(lèi)時(shí),不會(huì)被要求遵循許多Hibernate特定的規(guī)則和設(shè)計(jì)模式。這樣,Hibernate就可以與大多數(shù)新的和現(xiàn)有的應(yīng)用平穩(wěn)地集成,而不需要對(duì)應(yīng)用的其余部分作破壞性的改動(dòng)。更有意義的是Hibernate可以在應(yīng)用EJB的J2EE架構(gòu)中取代CMP,完成數(shù)據(jù)持久化的重任。
1.Hibernate框架的工作流程
Hibernate啟動(dòng)后,創(chuàng)建Configuration實(shí)例,利用此實(shí)例加載配置文件hibernate.cfg.xml到內(nèi)存中,通過(guò)hibernate.cfg.xml配置文件中的mapping節(jié)點(diǎn)配置并加載*.hbm.xml文件至該實(shí)例中,并利用此實(shí)例創(chuàng)建一個(gè)SessionFaetory實(shí)例,在由SessionFaetory實(shí)例得到Session的事務(wù)操作接口,利用此接口來(lái)操縱對(duì)數(shù)據(jù)庫(kù)的訪問(wèn),訪問(wèn)結(jié)束后關(guān)閉Session連接。
具體的Hibernate工作流程如圖2一4所示:

2. Hibernate框架的優(yōu)點(diǎn)
Hibernate作為持久層框架,其自身的優(yōu)勢(shì)使得Hibernate在企業(yè)級(jí)系統(tǒng)的應(yīng)用中越來(lái)越流行。Hibernate的優(yōu)勢(shì)主要體現(xiàn)在以下幾點(diǎn):
①對(duì)JDBC進(jìn)行了輕量級(jí)的對(duì)象封裝,使編程人員不必重復(fù)編寫(xiě)SQL代碼,結(jié)構(gòu)清晰,維護(hù)簡(jiǎn)單。
②Hibenate既適用于獨(dú)立的Java程序,也可以用于J2EE Web應(yīng)用,還可以在應(yīng)用EJB的J2EE架構(gòu)中取代CMP,完成數(shù)據(jù)持久化的重任。
③以統(tǒng)一的方式支持多種數(shù)據(jù)庫(kù)。
④由于是開(kāi)源的框架,可以對(duì)其代碼進(jìn)行修改,增加或修改功能。
⑤不僅提供了Java類(lèi)到數(shù)據(jù)表之間的映射,也提供了數(shù)據(jù)查詢和回復(fù)機(jī)制,避免了對(duì)數(shù)據(jù)庫(kù)的手工操作,大大減少了操作數(shù)據(jù)庫(kù)的工作量。
⑥可以和多種Web服務(wù)器或者應(yīng)用服務(wù)器良好集成,幾乎支持所有流行的數(shù)據(jù)庫(kù)服務(wù)器。
2.1.5Ajax技術(shù)
目前,Web應(yīng)用程序正在以幾何數(shù)量級(jí)的速度增長(zhǎng),其解決技術(shù)也正逐步成熟。Web應(yīng)用程序不再是簡(jiǎn)單顯示信息的網(wǎng)站,而逐步融合核心的業(yè)務(wù)
邏輯,成為了IT領(lǐng)域的業(yè)務(wù)處理平臺(tái)。但是在web應(yīng)用程序中,前端的用戶界面與后臺(tái)邏輯處理的同步交互過(guò)程越來(lái)越不是適應(yīng)用戶的需要,逐漸成為
Web應(yīng)用發(fā)展的瓶頸。
Ajax全稱為“Asynchronous JavaScript and XML”(異步JavaScript和XML),是指一種創(chuàng)建交互式網(wǎng)頁(yè)應(yīng)用的網(wǎng)頁(yè)開(kāi)發(fā)技術(shù)。Ajax技術(shù)的出現(xiàn)讓業(yè)界重新審視Web應(yīng)用程序的通信模式,對(duì)Web應(yīng)用程序的數(shù)據(jù)傳輸速度和用戶體驗(yàn)提出了更高的要求和期望,也讓業(yè)界看到了成功的曙光。
傳統(tǒng)的Web應(yīng)用程序采用同步交互過(guò)程。在這種情況下,用戶首先向Web服務(wù)器觸發(fā)一個(gè)行為請(qǐng)求;反過(guò)來(lái),服務(wù)器執(zhí)行某些任務(wù),再向發(fā)起請(qǐng)求的用戶返回一個(gè)HTML/XHTML頁(yè)面。這是一種不連貫的用戶體驗(yàn),服務(wù)器在處理請(qǐng)求的時(shí)候,用戶多數(shù)時(shí)間處于等待的狀態(tài),屏幕內(nèi)容也是一片空白。當(dāng)負(fù)載較大時(shí),用戶就必須在瀏覽器前等待很久才能得到需要的頁(yè)面,有時(shí)甚至出現(xiàn)打不開(kāi)頁(yè)面的情況。
與傳統(tǒng)的web應(yīng)用程序不同,Ajax采用異步交互過(guò)程,在用戶與服務(wù)器之間引入一個(gè)中間媒體,從而消除了在傳統(tǒng)Web應(yīng)用的網(wǎng)絡(luò)交互過(guò)程中處理—等待—處理—等待的缺點(diǎn)。
Ajax引擎允許用戶與應(yīng)用軟件之間交互過(guò)程異步進(jìn)行,獨(dú)立于用戶與網(wǎng)絡(luò)服務(wù)器間的交流。通過(guò)JavaScrint調(diào)用Ajax引擎來(lái)代替產(chǎn)生一個(gè)Http請(qǐng)求的用戶動(dòng)作,內(nèi)存中的數(shù)據(jù)編輯、頁(yè)面導(dǎo)航、數(shù)據(jù)校驗(yàn)、部分?jǐn)?shù)據(jù)加載顯示這些都不需要重新載入整個(gè)頁(yè)面的請(qǐng)求,可以交給Ajax來(lái)執(zhí)行。異步的Ajax傳輸過(guò)程如圖2-5所示:

Ajax技術(shù)的出現(xiàn),改變了傳統(tǒng)Web應(yīng)用程序的交互模式,為開(kāi)發(fā)人員、終端用戶帶來(lái)了便捷,在Web應(yīng)用中越來(lái)越流行。Ajax技術(shù)的優(yōu)點(diǎn)主要體現(xiàn)在以下幾個(gè)方面:
①減輕服務(wù)器的負(fù)擔(dān)。與傳統(tǒng)Web系統(tǒng)的更新整個(gè)頁(yè)面相比,Ajax可是對(duì)頁(yè)面內(nèi)容進(jìn)行實(shí)時(shí)更新,即只更新需要更新的部分,其余部分則保持不變。這種
“按需 取數(shù)據(jù)”的原則可以在相當(dāng)程度上減少冗余請(qǐng)求和響應(yīng)對(duì)服務(wù)器造成的負(fù)擔(dān)。
②無(wú)刷新更新頁(yè)面,減少用戶心理和實(shí)際的等待時(shí)間。特別地,當(dāng)要讀取大量數(shù)據(jù)地時(shí)候,不會(huì)像Reload那樣出現(xiàn)“白屏”的情況。
③進(jìn)一步促進(jìn)頁(yè)面呈現(xiàn)和數(shù)據(jù)的分離。
④可以把以前一些服務(wù)器擔(dān)負(fù)的工作轉(zhuǎn)嫁到客戶端,利用客戶端閑置的能力來(lái)處理,減輕了服務(wù)器和帶寬的負(fù)擔(dān),節(jié)約空間和寬帶租用成本。
⑤基于標(biāo)準(zhǔn)化的并被廣泛支持的技術(shù),無(wú)需下載插件或者小程序。
⑥跨瀏覽器和跨平臺(tái)的兼容性,可以在不同的瀏覽器(如IE、Firefox等)上建立基于Ajax的web應(yīng)用。
2.2ASSH框架的設(shè)計(jì)
ASSH框架是按照J(rèn)2EE三層結(jié)構(gòu)對(duì)Struts、Spring、Hibernate框架進(jìn)行整合并加入Ajax技術(shù)而形成的。在Web應(yīng)用系統(tǒng)開(kāi)發(fā)過(guò)程中,不同的層次采用不同的框架,表現(xiàn)層采用Struts MVC模式,并結(jié)合Ajax技術(shù)來(lái)增加系統(tǒng)與用戶交互的靈活性;業(yè)務(wù)邏輯層采用Spring框架,完成應(yīng)用系統(tǒng)的業(yè)務(wù)邏輯與事務(wù)處理等功能;數(shù)據(jù)持久層采用對(duì)象/關(guān)系映射工具Hibernate框架,完成與數(shù)據(jù)庫(kù)進(jìn)行數(shù)據(jù)交互的功能。ASSH框架中的整合包括:
①Struts框架與Spring框架的整合。
②Spring框架與Hibernate框架的整合。
③Ajax技術(shù)在表現(xiàn)層的應(yīng)用。
2.2.1Struts框架與Spring框架的整合
雖然Spring框架本身提供了一套極其優(yōu)秀的MVC框架,但這套框架的設(shè)計(jì)過(guò)于追求完美,采用了大量的映射策略,如請(qǐng)求到控制器之間的控制器解析策略,邏輯視圖和實(shí)際視圖之間的視圖解析策略等;還有過(guò)于細(xì)化的角色劃分,使得MVC層的開(kāi)發(fā)相當(dāng)煩瑣。這對(duì)于實(shí)際應(yīng)用的開(kāi)發(fā)往往弊大于利,而且Spring MVC的開(kāi)發(fā)群體不夠活躍,也存在風(fēng)險(xiǎn)。
而采用Struts框架將不存在這些風(fēng)險(xiǎn),它擁有極其穩(wěn)定的表現(xiàn),經(jīng)過(guò)長(zhǎng)時(shí)間的檢驗(yàn),有大量成功的應(yīng)用可以參考。
將StrutsMVC與SPring框架整合有三種方法:
(1)使用Spring的ActionSupport類(lèi)整合Struts;
(2)使用Spring的DelegatingRequestProeessor覆蓋Struts的RequestProeessor;
(3)將StrutSAction管理委托給Spring框架。
1.使用Spring的ActionSupport類(lèi)整合Structs
手動(dòng)創(chuàng)建一個(gè)Spring環(huán)境是一種整合Struts和Spring的最直觀的方式。為了使它變得更簡(jiǎn)單,Spring提供了一些幫助。為了方便地獲得Spring環(huán)境,org.sprinsframework.web.struts.ActionSupport類(lèi)提供了一個(gè)getWebApplicationContextO方法。我們所做的只是從Spring的ActionSupport而不是StrutsAction類(lèi)擴(kuò)展我們所需要的動(dòng)作,如下面代碼所示:

在①處,通過(guò)從Spring的ActionSupport類(lèi)而不是Struts的Action類(lèi)進(jìn)行擴(kuò)展,創(chuàng)建了一個(gè)新的Action。在②處,使用getWebAppliationContext()方法獲得一個(gè)ApplicationContext。為了獲得業(yè)務(wù)服務(wù),使用在②處獲得的環(huán)境在③處查找一個(gè)Spring bean。
2.通過(guò)Spring的DelegatingRequestProeessor進(jìn)行整合
將Spring從Struts動(dòng)作中分離是一個(gè)更巧妙的設(shè)計(jì)選擇。分離的一種方法是使用org.springframework.web.struts.DelegatingRequestProeessor類(lèi)來(lái)覆蓋Struts的RequestProcessor處理程序,在struts-config.xml文件中添加<controller>標(biāo)記,用DelegatingRequestProcessor覆蓋默認(rèn)的StrutsRequestProeessor。具體代碼如下:
<controller proeessorClass = "org.springframework.web.struts.DelegatingRequestPoeessor" />
同時(shí)在Spring的配置文件applieationContext.xml中注冊(cè)一個(gè)bean,以匹配Struts-config中的動(dòng)作映射名稱。具體代碼如下:

TestSubmit動(dòng)作揭示了一個(gè)JavaBean屬性,允許Spring在運(yùn)行時(shí)利用DelegatingRequestProeessor自動(dòng)地配置屬性。這種設(shè)計(jì)使Struts動(dòng)作并不知道它正被Spring管理,并且使能夠利用Sping的動(dòng)作管理框架的所有優(yōu)點(diǎn)。由于Struts動(dòng)作注意不到Spring的存在,所以不需要重寫(xiě)Struts代碼就可以使用其他控制反轉(zhuǎn)容器來(lái)替換掉Spring。
3.通過(guò)StrutsAction的管理委托進(jìn)行整合
首先在struts-config.xml文件中注冊(cè)Spring插件如下所示:
<plug-in className = "org.springframework.web.struts.ContextLoaderPlugIn" />
<set-property property = "contextConfigLoeation" value = "WEB-INF/applicationContext.xml" />
</plug-in>
其次將所有action標(biāo)簽中type屬性設(shè)為org.springframework.web.struts.DelegatingActionProxy,也就是將action委托給了Spring。因而在Spring配置文件applicationContext.xml
中配置一個(gè)于action標(biāo)簽path屬性對(duì)應(yīng)的bean(也就是bean的name值等于action的path值),如:
struts-config.xml的代碼片段

applicationContext.xml的代碼片段

三種整合方法的對(duì)比:
使用Spring的ActionSupport來(lái)整合Struts簡(jiǎn)單而快捷。但是,它將Struts動(dòng)作與Spring框架耦合在一起,如果想替換掉Spring的話,就必須重寫(xiě)代碼。并且,由于Struts動(dòng)作不在Spring的控制之下,所以它不能獲得Spring AOP的優(yōu)勢(shì)。當(dāng)使用多重獨(dú)立的Spring環(huán)境時(shí),這種技術(shù)可能有用,但是在大多數(shù)情況下,這種方法不如另外兩種方法合適
第二種方法通過(guò)委托RequestProcessor巧妙地解開(kāi)代碼的耦合,彌補(bǔ)了第一種方法的不足,但是仍然存在一些問(wèn)題,例如要使用一個(gè)不同的RequestProeessor,則需要手動(dòng)整合Spring的DelegatingRequestProcessor。添加的代碼會(huì)為后期維護(hù)帶來(lái)麻煩并且會(huì)降低應(yīng)用程序的靈活性。
通過(guò)StrutsAction的管理委托進(jìn)行整合是這三種方法中最好的。將StrutsAction委托給Spring框架可以使代碼解耦,從而使可以在Struts應(yīng)用程序中利用Spring的特性。并且一旦讓Spring控制StrutsAction,就可以使用Spring給Action補(bǔ)充更強(qiáng)的活力。例如,沒(méi)有Spring的話,所有的StrutsAction都必須是線程安全的。如果設(shè)置<bean>標(biāo)一記的Singleton屬性為“false”,那么不管用何種方法,應(yīng)用程序都將在每一個(gè)請(qǐng)求上有一個(gè)新生成的動(dòng)作對(duì)象。在本文所設(shè)計(jì)的ASSH框架中Spring和Struts的整合
使用的是第三種方法。
2.2.2 Spring框架與Hibernate框架的整合
Spring作為一個(gè)開(kāi)放的框架在數(shù)據(jù)庫(kù)訪問(wèn)層上和主流的ORM軟件集成就是其重要組成部分。Hibernate最重要的配置文件是hibernate.cfg.xml。在這個(gè)配置文件中,可以定義需要進(jìn)行持久化的類(lèi)以及相關(guān)的一些全局屬性。而Spring通過(guò)LocalSessionFactoryBean這個(gè)類(lèi)對(duì)Hibernate進(jìn)行封裝和接口轉(zhuǎn)換,這樣可以使用統(tǒng)一的方式來(lái)處理Spring和Hibernate,同時(shí)提供一個(gè)全局的SessionFactory。并且Spring還提供了很多IOC特性的支持,方便地處理大部分典型的Hibernate整合問(wèn)題,如SessionFactory的注入、HibernateTemplate的簡(jiǎn)化操作及DAO支持等。
一旦Hibernate處于Spring的管理下,Hibernate所需要的基礎(chǔ)資源,都由Spring提供注入。Hibernate創(chuàng)建SessionFactory必需的Datasource,執(zhí)行持久化必需的Session及持久層訪問(wèn)必需的事務(wù)控制等,這些原本必須通過(guò)代碼控制的邏輯,都將由Spring接管Datasource,SessionFactory,TransactionManager等,都將作為Spring容器中的bean。Spring通過(guò)
applicationContext.xml文件管理SessionFactory,無(wú)須采用單獨(dú)Hibernate應(yīng)用所必需的hibernate.cfg.xml文件。
Spring通過(guò)applicationContext.xml文件配置管理SessionFactory與數(shù)據(jù)庫(kù)的連接。在實(shí)際的J2EE應(yīng)用中,數(shù)據(jù)源采用依賴注入的方式,將SessionFactory傳給Hibernate。具體applicationContext.xml的配置如下所示:





SessionFactory由applicationContext.xml管理,并隨著應(yīng)用程序啟動(dòng)時(shí)自動(dòng)加載,可以被處于applicationContext.xml管理下的任意一個(gè)bean引用,比如DAO。Hibernate的數(shù)據(jù)庫(kù)訪問(wèn)需要在Session管理下,而SessionFactory是Session的工廠。Spring采用依賴注入的方式為DAO對(duì)象注入SessionFactory的引用。
Spring還提供了HibernateTemplate用于持久層訪問(wèn),該模板類(lèi)無(wú)須顯示打開(kāi)Session及關(guān)閉Session。它只要獲得SessionFactory的引用,就可以自動(dòng)打開(kāi)Session,并在持久化訪問(wèn)結(jié)束后關(guān)閉Session,程序開(kāi)發(fā)只需完成持久層邏輯,通用的操作則由HibernateTemplate完成。例如,要把某條數(shù)據(jù)存入的數(shù)據(jù)庫(kù)中只需寫(xiě)如下代碼即可,而不必關(guān)心Session的打開(kāi)和關(guān)閉:getHibernateTemplate().save(object)。
通過(guò)Spring整合Hibernate,使持久層的訪問(wèn)更加容易,使用Spring管理Hibernate持久層有如下優(yōu)勢(shì):
①通用的資源管理:spring使用applicationContext.xml管理SessionFactory,使得配置值很容易被管理和修改,無(wú)須使用Hibernate的配置文件。
②有效的Session管理:Spring提供了有效、簡(jiǎn)單和安全的Hibernate Session處理。
③IOC容器提高了DAO組件與業(yè)務(wù)邏輯層之間的解耦。
④DAO模式的使用,降低了系統(tǒng)重構(gòu)的代價(jià)。
⑤方便的事務(wù)管理:Hibernate的事務(wù)管理處理會(huì)限制Hibernate的表現(xiàn),而Spring的聲明式事務(wù)管理力度是方法級(jí)。
⑥異常包裝:Spring能夠包裝Hibernate異常,把它們從cheeked exeeption變?yōu)閞untimeException;開(kāi)發(fā)者可選擇在恰當(dāng)?shù)膶犹幚頂?shù)據(jù)中不可恢復(fù)的異常,從而避免
煩瑣的Catch/throw及異常聲明。
2.2.3 Ajax技術(shù)在表現(xiàn)層的應(yīng)用
Ajax技術(shù)在框架中的應(yīng)用使得整個(gè)系統(tǒng)與用戶交互的靈活性增加,界面設(shè)計(jì)更加人性化,下面以“基礎(chǔ)信息管理”模塊中為大項(xiàng)目添加小項(xiàng)目為例來(lái)介紹Ajax技術(shù)在系統(tǒng)中的應(yīng)用。
1.編寫(xiě)JavaScript事件處理的js文件
2.為頁(yè)面的目標(biāo)控件中添加事件觸發(fā)屬性
3.在頁(yè)面中添加事件響應(yīng)函數(shù)SendRequest()
4.編寫(xiě)后臺(tái)業(yè)務(wù)邏輯處理程序
5.在頁(yè)面中添加響應(yīng)處理函數(shù)callBackRequest(xmlHttpRequest)
2.3ASSH框架與其他解決方案的比較
本文設(shè)計(jì)的ASSH框架是由Struts、Spring、Hibernate以及Ajax技術(shù)整合而成的。其中以Struts負(fù)責(zé)表現(xiàn)層,以Spring負(fù)責(zé)業(yè)務(wù)邏輯層,以Hibernate負(fù)責(zé)數(shù)據(jù)持久層,在表現(xiàn)層加入Ajax技術(shù)對(duì)頁(yè)面進(jìn)行優(yōu)化。
在表現(xiàn)層,目前比較好的軟件框架有Struts、webworks、Spring MVC、TaPestry、JSF等。相對(duì)于其他框架Struts的優(yōu)勢(shì)主要體現(xiàn)在以下幾點(diǎn):
①以HTTP為中心:Struts設(shè)計(jì)圍繞標(biāo)準(zhǔn)HTTP請(qǐng)求一響應(yīng)模式,為許多Web開(kāi)發(fā)人員所熟悉。
②強(qiáng)大的標(biāo)簽庫(kù):利用Struts提供的taglib可以大大節(jié)約開(kāi)發(fā)時(shí)間,簡(jiǎn)化構(gòu)造和開(kāi)發(fā)應(yīng)用程序的過(guò)程。
③可擴(kuò)展性:所有默認(rèn)的設(shè)置都可以配置。核心Struts類(lèi)可以被重寫(xiě)和子類(lèi)化。開(kāi)發(fā)人員可以定制關(guān)鍵類(lèi)如ActionForm和Action。
④邏輯名稱的特性能夠?qū)⒁晥D層與模型層隔離開(kāi),使得任何一方的改變不會(huì)影響到另一方,使系統(tǒng)禍合性降低。
⑤表單驗(yàn)證解決了請(qǐng)求數(shù)據(jù)的驗(yàn)證問(wèn)題,增強(qiáng)了系統(tǒng)健壯性。
⑥頁(yè)面導(dǎo)航使系統(tǒng)的業(yè)務(wù)流程脈絡(luò)清晰,系統(tǒng)各部分之間的聯(lián)系可以通過(guò)配置文件反映出來(lái),從而簡(jiǎn)化了系統(tǒng)后期的維護(hù)工作。
⑦框架己經(jīng)非常成熟,有著眾多的開(kāi)發(fā)群體,使產(chǎn)品有穩(wěn)定的發(fā)展保障。
在傳統(tǒng)的J2EE Web應(yīng)用開(kāi)發(fā)中,通常使用EJB技術(shù)實(shí)現(xiàn)系統(tǒng)的業(yè)務(wù)邏輯處理,而且業(yè)務(wù)邏輯處理常常與表現(xiàn)層混雜在一起,為系統(tǒng)的后期維護(hù)與擴(kuò)展帶來(lái)了難以估計(jì)的困難。本文按照J(rèn)2EE三層結(jié)構(gòu)將業(yè)務(wù)邏輯層獨(dú)立出來(lái),用Spring框架來(lái)實(shí)現(xiàn),與EJB相比,Spring在提供服務(wù)時(shí)具有更大的靈活性,例如:對(duì)于不同的應(yīng)用程序,你可能希望選擇不同的企業(yè)級(jí)服務(wù)。譬如說(shuō),如果使用EJB,事務(wù)管理就必須使用JTA,哪怕你只使用一個(gè)數(shù)據(jù)庫(kù)也是如此;而如果使用AOP,你在這種情況下就可以選擇JDBC事務(wù)管理器,后者的性能開(kāi)銷(xiāo)比JTA要低得多。Spring框架允許以這種可接插的方式獲得企業(yè)級(jí)服務(wù),從而使你可以按需選擇企業(yè)級(jí)服務(wù)。基于AOP的方案可以將企業(yè)級(jí)服務(wù)(以及所有的聲明性服務(wù))提供給POJO。這與輕量級(jí)容器提供的無(wú)侵入性是一致的,AOP方案的可測(cè)試性也高于EJB編程模型。
并且Spring框架還具有以下優(yōu)勢(shì):
①促使我們面向接口編程,遵循好的OO習(xí)慣,這給我們帶來(lái)了可接插能力和可測(cè)試性。
②讓我們可以用統(tǒng)一的方式管理應(yīng)用程序的全部配置信息。
③基于標(biāo)準(zhǔn)的JeanBean基礎(chǔ)構(gòu)架。應(yīng)用對(duì)象通常以JeanBean的形式實(shí)現(xiàn),通過(guò)JeanBean屬性就可以配置簡(jiǎn)單參數(shù)和協(xié)作對(duì)象的依賴關(guān)系。
④消除難于測(cè)試的Singletion模式,并且不再需要在應(yīng)用代碼中進(jìn)行資源查找(這通常涉及難于在測(cè)試環(huán)境下模擬的API,例如JNDI),從而改善可測(cè)試性。
⑤Spring提供了數(shù)據(jù)持久框架,可以采用JDBC,或者類(lèi)似Hibernate的O/R mapping產(chǎn)品實(shí)現(xiàn)數(shù)據(jù)存取。
在數(shù)據(jù)持久層的主流解決方案除了Hibernate框架外,還有JDBC、EJB、JDO。
JDBC是低級(jí)別的數(shù)據(jù)庫(kù)訪問(wèn)方式,JDBC并不支持面向?qū)ο蟮臄?shù)據(jù)庫(kù)表示。JDBC數(shù)據(jù)庫(kù)表示完全圍繞關(guān)系數(shù)據(jù)庫(kù)模型。在大型應(yīng)用程序的DAO中書(shū)寫(xiě)這樣的代碼,維護(hù)量是非常大的。
EJB定義了兩種持久化的解決方案:一種是BMP,另一種是CMP。其中CMP不需要將SQL語(yǔ)句加入到代碼中。目前,在采用J2EE的應(yīng)用中,EJB CMP方式得到了廣泛應(yīng)用。但是,CMP的使用比較復(fù)雜,對(duì)很多開(kāi)發(fā)人員來(lái)說(shuō)比較難以掌握。而且,不是在所有的情況下都適合在系統(tǒng)中采用EJB,而且想要非常清楚的了解EJB規(guī)范也是非常費(fèi)時(shí)的。在用EJB編碼前,先要讓專家理解API,然后需要了解每一個(gè)容器部署時(shí)所要關(guān)注的技術(shù)。
JDO是一個(gè)存儲(chǔ)Java對(duì)象的規(guī)范,JDO規(guī)范1.0的提出可以使你將精力集中在設(shè)計(jì)Java對(duì)象模型,然后在企業(yè)應(yīng)用軟件架構(gòu)的不同層面中存儲(chǔ)傳統(tǒng)的Java對(duì)象(Plain Old Java Objects,簡(jiǎn)稱POJOs),采用JDOQL語(yǔ)言進(jìn)行SQL操作。一些公司(包括Sun)企圖根據(jù)JDO規(guī)范進(jìn)行設(shè)計(jì)并實(shí)現(xiàn)JDO產(chǎn)品,然而他們都不能很好的進(jìn)行實(shí)現(xiàn),并且性能優(yōu)化上比較差。
Hibernate是一個(gè)開(kāi)放源代碼的對(duì)象關(guān)系映射框架,它對(duì)JDBC進(jìn)行了輕量級(jí)的對(duì)象封裝,使Java程序員可以隨心所欲的使用對(duì)象編程思維來(lái)操縱數(shù)據(jù)庫(kù)。它不僅提供了從Java類(lèi)到數(shù)據(jù)表之間的映射,也提供了數(shù)據(jù)查詢和恢復(fù)機(jī)制。相對(duì)于使用JDBC和SQL來(lái)手工操作數(shù)據(jù)庫(kù),Hibernate可以大大減少操作數(shù)據(jù)庫(kù)的工作量。另外Hibernate可以利用代理模式來(lái)簡(jiǎn)化載入類(lèi)的過(guò)程,這將大大減少利用Hibernate QL從數(shù)據(jù)庫(kù)提取數(shù)據(jù)的代碼的編寫(xiě)量,從而節(jié)約開(kāi)發(fā)時(shí)間和開(kāi)發(fā)成本Hibernate可以和多種Web服務(wù)器或者應(yīng)用服務(wù)器良好集成,如今已經(jīng)支持幾乎所有的流行的數(shù)據(jù)庫(kù)服務(wù)器。
在傳統(tǒng)Web應(yīng)用系統(tǒng)中,存在用戶為了調(diào)用某項(xiàng)功能而在大量的頁(yè)面間跳轉(zhuǎn)的問(wèn)題。雖然說(shuō)這并不是一個(gè)很大的問(wèn)題,而且用戶所需要的功能都已經(jīng)實(shí)現(xiàn),但是頻繁的頁(yè)面跳轉(zhuǎn),甚至有些是重復(fù)的跳轉(zhuǎn)充斥在用戶的操作過(guò)程中,容易使用戶產(chǎn)生厭煩感,從而對(duì)軟件的認(rèn)可度降低。俗話說(shuō)“細(xì)節(jié)決定成敗”,也許正因?yàn)檫@樣一個(gè)微不足道的細(xì)節(jié)成為用戶放棄我們所開(kāi)發(fā)的系統(tǒng)的原因。
Ajax技術(shù)的使用可以使Web系統(tǒng)在不刷新整個(gè)頁(yè)面的前提下維護(hù)數(shù)據(jù)。這使得Web應(yīng)用程序更為迅捷地響應(yīng)用戶交互,并避免了在網(wǎng)絡(luò)上發(fā)送那些沒(méi)有改變的信息,提高了系統(tǒng)的可操作性。
本文出自 張賓
基于ASSH框架的J2EE WEB應(yīng)用與實(shí)現(xiàn)
posted on 2009-05-07 17:48
特立獨(dú)行 閱讀(762)
評(píng)論(0) 編輯 收藏 所屬分類(lèi):
J2EE核心技術(shù)