總算將一個(gè)項(xiàng)目勉強(qiáng)上線,也是第一次我獨(dú)立完成的這么多任務(wù),框架設(shè)計(jì)、框架搭建、代碼編寫、測試、數(shù)據(jù)庫創(chuàng)建、表結(jié)構(gòu)設(shè)計(jì)……除了頁面和詳細(xì)設(shè)計(jì)我都做了個(gè)遍,雖然很倉促也犯了很多錯(cuò)誤,但是整個(gè)過程走下來,發(fā)現(xiàn)自己真的學(xué)到不少東西。在這個(gè)空檔期寫個(gè)小總結(jié),以便以后使用 :)
現(xiàn)在框架真是多的要死,也沒有什么真正能一統(tǒng)天下的東西,每個(gè)人的著眼點(diǎn)和技術(shù)習(xí)慣都不同,在剛接到項(xiàng)目的時(shí)候,老大就要我自己去確定框架。當(dāng)時(shí)我正沉迷于TapeStry+Spring+iBatis開發(fā)的暢快之中,當(dāng)時(shí)真想直接將自己的東西移植過去,但是一想公司陸續(xù)會(huì)有其他人進(jìn)來加入到項(xiàng)目中,那么TSS這個(gè)框架肯定很難找到合適的人選,而且自己在研究TSS的過程中也發(fā)現(xiàn)由于文檔的缺乏,遇到問題的解決就是一個(gè)很嚴(yán)重的問題,最終只能棄用。雖然我很喜歡T4,但是它實(shí)在不讓人放心,只好期待Howard能給我們不斷帶來驚喜,真正成為繼Struts、WebWork之后的最優(yōu)選擇。有時(shí)間我還會(huì)繼續(xù)學(xué)習(xí)T4,并做一下總結(jié)。
經(jīng)過當(dāng)時(shí)的考慮,我只得放棄TSS,最終選擇自己相對熟悉的Struts+Spring+Hibernate,說是熟悉,那是因?yàn)橐郧暗捻?xiàng)目是用這個(gè),有網(wǎng)友戲稱SSH是庸俗組合,呵呵,庸俗就庸俗吧,我想自己能把這套東西搞好也會(huì)有相當(dāng)?shù)碾y度的(現(xiàn)在證明這個(gè)選擇是對的,出了問題有人問,項(xiàng)目組的其他人也都是玩這套東西的,維護(hù)擴(kuò)展都方便)。
具體細(xì)節(jié)就不再描繪了,做軟件的都知道問題無法解決是多么的折磨人,這其中的酸甜苦辣只有經(jīng)歷過的人才知道,技術(shù)上的問題是遇到一個(gè)解決一個(gè),實(shí)在覺得解決不了或者沒有把握,利馬換其他想法,這個(gè)很重要,實(shí)現(xiàn)的方法有很多,即便不是最優(yōu)的解決方案,但是節(jié)省的大量的時(shí)間,在工期緊的時(shí)候一定要權(quán)衡的去考慮,否則后果不堪設(shè)想。
總體框架(SSH)需要4個(gè)重要的配置文件:
1.web.xml
2.Struts-config.xml
3.applicationContext.xml
4個(gè)文件中的大多數(shù)配置都是很普通的,只在這記錄一些比較容易出問題的地方,
web.xml中配置了OpenSessionInViewFilter,這個(gè)東西是我在整個(gè)框架構(gòu)建中浪費(fèi)最多時(shí)間也是出現(xiàn)問題最多的地方,后來和項(xiàng)目組同事討論,最終在新的項(xiàng)目中放棄了對這爛東西的使用,如果使用延遲加載,那么所有需要加載的東西應(yīng)該在Dao中使用Hibernate.initialize(object)強(qiáng)制加載,使得持久化操作保持在Dao層中完成,徹底拋棄OpenSesionInViewFilter。HOHO
Spring ContextListner 的加載仍然放在web.xml里面進(jìn)行,盡管在Struts中使用了ContextLoaderPlugin,但僅僅是在加載StrutsAction的時(shí)候才使用到,而整個(gè)SpringContext的初始化仍然是放在web.xml里面進(jìn)行。個(gè)人覺得這樣做肯定有很多好處,但是目前仍不能說出真正的緣由。如此配置的初衷還是因?yàn)橛玫搅薕penSessionInViewFilter,因?yàn)槿绻赟truts中去初始化Spring,OpenSessionInViewFilter根本跑不起來,因?yàn)樗旧硎窃趙eb.xml中初始化的,而且需要ContextListner 的支持。必須配置在web.xml中,此時(shí)仍使用ContextLoaderPlugin來加載就會(huì)出現(xiàn)Spring被加載兩次的情況,結(jié)果造成OpenSessionInViewFilter失效。盡管現(xiàn)在不再使用那個(gè)Filter,配置卻仍然這樣保持下來,我覺得仍然可以避免一些問題,畢竟配置在Struts下面就被Struts綁死了,那么好像是 Struts在控制整體,違背了框架搭建的初衷,也無法使Spring發(fā)揮自己最大的功力。
Struts-config.xml中有3個(gè)需要注意的地方,第一個(gè)是使用DelegatingActionProxy,我曾經(jīng)對我項(xiàng)目組的同事每個(gè)人都解釋了一遍為什么要使用這個(gè)東東,真是痛苦的要死。但是這個(gè)東西一直都被認(rèn)為是Struts+Spring最好的配置方式,其他的諸如使用WebLoadContext那種方式好像都無法帶來這樣的好處。我覺得這樣用的好處是:就如它的名字一樣,Proxy,Struts在使用它的時(shí)候根本不知道它的存在,幾乎感覺不到影響,只是把配置文件寫到beans.xml中去了。第二個(gè)好處是Struts的線程安全問題,如此配置新的線程不再共享同一個(gè)Action,更高深的東西我也說不清楚了 :(。第三個(gè)好處就是方便的使用AOP,這個(gè)是我最喜歡的了,有了這個(gè)Proxy,StrutsAction才真正的成為Spring轄區(qū)的一部分,方便的使用AOP,我不知道沒有AOP我需要多寫幾千行代碼,這對項(xiàng)目的及時(shí)完工真是不知道作出多少貢獻(xiàn),也使得框架更加優(yōu)雅,極盡贊美之詞也不為過。:P
第二個(gè)注意的地方是使用了Tiles框架,盡管后來美工給我Frame框架的時(shí)候造成了很多麻煩,可我仍然挺喜歡Tiles,心想如果我在用T4的時(shí)候能那么輕易的使用Tiles當(dāng)時(shí)真的就用TSS也說不一定哦。Tiles里面基礎(chǔ)配置沒什么可說的,tiles-defs.xml、layout.jsp,頁面上的使用寫正確配置就可以了,但是在使用Tiles的時(shí)候遇到一個(gè)預(yù)加載JS的需求,要不是手頭有以前項(xiàng)目的代碼,估計(jì)就玩完了
看上去很普通的代碼,但是其中使用了tiles的一個(gè)樹型 ignore="true", 才真正使得預(yù)加載JS變得更加方便和可控制,這樣我就不用在每個(gè)布局模板上都寫上一個(gè)沒有意義的空方法在里面咯。
第三個(gè)問題是使用Validation框架,盡管以前使用過,但是自己用的時(shí)候才知道配置起來沒那么簡單,最初我采用Struts-1.2.9版本,沒想到Validation不能用,后來在網(wǎng)上發(fā)現(xiàn)Validation用的包不全是Struts自帶的,版本不統(tǒng)一導(dǎo)致了Validation問題多多,折磨我好多天,最終不得不放棄Struts1.2.9而降級(jí)到1.2.8,才使得問題得以解決。
applicationContext.xml中的配置也相對要穩(wěn)定一些,需要什么加什么就好了,當(dāng)時(shí)我為了將JUnit分離出來還特地請教了一位高人,JUnit分離其實(shí)有很大的意義,它不但真正意義上脫離了Web環(huán)境還使得測試數(shù)據(jù)和真實(shí)數(shù)據(jù)的分離。利用好JUnit絕對是提高開發(fā)效率的一件法寶,難怪有很多大師級(jí)的人物都說編寫測試用例要比編寫代碼挑戰(zhàn)大得多。但是項(xiàng)目最終的遺留問題讓我被迫放棄了這個(gè)JUnit分離:(,原因是我無法解決相對路徑的查找,項(xiàng)目中大量用到了Socket、線程、任務(wù)計(jì)劃這種東西,使得相對路徑的問題多多,沒辦法我只能盡量縮減配置文件的數(shù)目,不知道有沒有更好的解決方案。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1028413