1 SSH在開發(fā)中的位置

現(xiàn)在J2EE的開源框架多的數(shù)不清楚,目前(已經(jīng)、正在)比較流行的常用框架大概有struts,spring,hibernate,jsf,webwork,而 struts+spring+hibernate(SSH)這種輕量級(jí)架構(gòu)被譽(yù)為“黃金組合”。spring和hibernate更是被許多人認(rèn)為是未來(lái)五年內(nèi)不會(huì)被淘汰的技術(shù),猶如當(dāng)年的struts,今天的開發(fā)中依然被廣泛采用。

2 為什么使用SSH  

其實(shí),就算用Java建造一個(gè)不是很煩瑣的web應(yīng)用,也不是件輕松的事情。 在構(gòu)架的一開始就有很多事情要考慮。從高處看,擺在開發(fā)者面前有很多問(wèn)題:要考慮是怎樣建立用戶接口?在哪里處理業(yè)務(wù)邏輯? 怎樣持久化的數(shù)據(jù)。 而這三層構(gòu)架中,每一層都有他們要仔細(xì)考慮的。 各個(gè)層該使用什么技術(shù)?怎樣的設(shè)計(jì)能松散耦合還能靈活改變? 怎樣替換某個(gè)層而不影響整體構(gòu)架?應(yīng)用程序如何做各種級(jí)別的業(yè)務(wù)處理(比如事務(wù)處理)?

    構(gòu)架一個(gè)Web應(yīng)用需要弄明白好多問(wèn)題。 幸運(yùn)的是,已經(jīng)有不少開發(fā)者已經(jīng)遇到過(guò)這類問(wèn)題,并且建立了處理這類問(wèn)題的框架。 一個(gè)好框架具備以下幾點(diǎn):減輕開發(fā)者處理復(fù)雜的問(wèn)題的負(fù)擔(dān)("不重復(fù)發(fā)明輪子");內(nèi)部有良好的擴(kuò)展; 并且有一個(gè)支持它的強(qiáng)大的用戶團(tuán)體。 好的構(gòu)架一般有針對(duì)性的處理某一類問(wèn)題,并且能將它做好(Do One Thing well)。 然而,你的程序中有幾個(gè)層可能需要使用特定的框架,已經(jīng)完成的UI(用戶接口) 并不代表你也可以把你的業(yè)務(wù)邏輯和持久邏輯偶合到你的UI部分。 舉個(gè)例子,你不該在一個(gè)Controller(控制器)里面寫JDBC代碼作為你的業(yè)務(wù)邏輯, 這不是控制器應(yīng)該提供的。 一個(gè)UI 控制器應(yīng)該委派給其它給在UI范圍之外的輕量級(jí)組件。 好的框架應(yīng)該能指導(dǎo)代碼如何分布。 更重要的是,框架能把開發(fā)者從編碼中解放出來(lái),使他們能專心于應(yīng)用程序的邏輯(這對(duì)客戶來(lái)說(shuō)很重要)。 

他們里面有很我優(yōu)秀的設(shè)計(jì)理念及模式應(yīng)用。比如, struts屬于MVC框架,關(guān)鍵是要了解MVC的概念及大致原理,掌握就很容易了;而hibernate屬于orm系統(tǒng),屬于持久層的解決方案,同樣需要對(duì)ORM的概念及原理有一個(gè)總體的了解,必要時(shí)可以去查查EJB1及EJB2里面用于持久層的Entity Bean的使用。而spring屬于應(yīng)用程序框架,其核心是IOC容器以及AOP,把這兩個(gè)核心概念(也可稱為大模式)了解以后,再加上一定的內(nèi)力修為,其它就都不難了。Spring中還集成了很多適用東西(不過(guò)這些東西80%的在某一個(gè)項(xiàng)目中可能一直用不上),比如對(duì)JDBC的封裝、自己的MVC、對(duì)動(dòng)態(tài)語(yǔ)言的簡(jiǎn)潔訪問(wèn)等,這些你根據(jù)自己的項(xiàng)目情況來(lái)選擇學(xué)習(xí),用到的時(shí)候再看看他的文檔,一個(gè)項(xiàng)目下來(lái)應(yīng)該就能把握。

3 對(duì)于SSH的理解

在SSH框架中,struts用來(lái)解決MVC中顯示、請(qǐng)求控制部分,spring主要負(fù)責(zé)訪問(wèn)數(shù)據(jù)庫(kù)DAO類的事務(wù)控制以及它被人稱譽(yù)的IOC思想在業(yè)務(wù)類中的恰當(dāng)運(yùn)用,hibernate主要是充當(dāng)數(shù)據(jù)訪問(wèn)層組件。由于spring對(duì)hibernate的良好支持,在DAO類主要由spring來(lái)完成,hibernate更多關(guān)注的應(yīng)是O/R影射文件上的配置,如級(jí)聯(lián)關(guān)系,延遲加載等如何設(shè)置才能使效率更高。見圖1 (框架組合示意圖)

4 收獲和問(wèn)題

4.1 actionform,PO,VO三對(duì)象的運(yùn)用

討論最多的是actionform,PO,VO三對(duì)象的運(yùn)用,本人傾向的觀點(diǎn)是:在SSH框架中,PO和VO可以不必區(qū)分,即業(yè)務(wù)層和持久層都可以使用hibernate產(chǎn)生的PO對(duì)象,我暫時(shí)把對(duì)象分成actionform和po兩種來(lái)分析,action 應(yīng)該是actionform和po的分界點(diǎn),po不能穿透業(yè)務(wù)層,突破action到達(dá)頁(yè)面顯示層,同樣actionform也不能突破action傳到后臺(tái)業(yè)務(wù)、持久層。(原因:po是持久對(duì)象,到達(dá)頁(yè)面后就脫離了session成為無(wú)狀態(tài)(暫理解為脫管態(tài))的對(duì)象,而hibernate的持久對(duì)象是有狀態(tài)(包含數(shù)據(jù)庫(kù)主鍵)的,無(wú)狀態(tài)的對(duì)象傳到后臺(tái)在調(diào)用hibernate的保存方法時(shí)會(huì)出錯(cuò),一定要把無(wú)狀態(tài)的對(duì)象先轉(zhuǎn)化成持久態(tài)對(duì)象才能保存)在action中應(yīng)該對(duì)兩對(duì)象進(jìn)行轉(zhuǎn)化,轉(zhuǎn)化的方法目前我還沒發(fā)現(xiàn)有什么非常好的方法(歡迎高手不惜賜教),最普通的就是用get(),set()方法,也可以使用struts提供的屬性復(fù)制方法BeanUtils類,但這個(gè)好象只支持單個(gè)類的轉(zhuǎn)化,對(duì)于集合對(duì)象不行,需要我們自己擴(kuò)展。

4.2 spring事務(wù)管理

在配置spring的事務(wù)管理中,最好把事務(wù)控制配置在業(yè)務(wù)類上,而不要配置在DAO類(需要保證多個(gè)原子事務(wù)操作同時(shí)失敗回滾時(shí)這是一種解決辦法);

4.3 action如何獲取業(yè)務(wù)類

action中如何獲取業(yè)務(wù)類:寫一個(gè)父類action,在父類中通過(guò)spring的webapplicationcontent獲得業(yè)務(wù)類的實(shí)例。struts中的具體action繼承該父類,通過(guò)調(diào)用父類的getService()直接獲得業(yè)務(wù)類的實(shí)例。

4.4 理解AOP思想

深入理解AOP思想,我暫時(shí)感覺到的就是盡量面向接口編程,不管是域?qū)ο筮€是業(yè)務(wù)類或者是DAO類都設(shè)計(jì)出接口,在各方法中我們盡量傳入對(duì)象的接口,這對(duì)我們重用這些方法,擴(kuò)展是很有好處的。

4.5 分頁(yè)處理 level

5 系統(tǒng)包劃分

這是一個(gè)真實(shí)項(xiàng)目的例子:

系統(tǒng)包劃分

包名

描述

com.projectname.domain

邏輯調(diào)用信息的載體Bean和hibernate的配置

com.projectname.lgc

邏輯層服務(wù)封裝的接口或抽象類

com.projectname.dao

數(shù)據(jù)庫(kù)訪問(wèn)的抽象類

com.projectname.dao.impl

數(shù)據(jù)庫(kù)操作的具體實(shí)現(xiàn)

com.projectname.web.action

控制頁(yè)面跳轉(zhuǎn)或Servlet

com.projectname.common

系統(tǒng)通用