首先,必須承認(rèn),turbine作為一個(gè)開(kāi)發(fā)框架,已經(jīng)快絕跡了,阿里巴巴的webx框架是基于turbine做的,所以這里簡(jiǎn)單介紹一下,如果是阿里系新入職的同學(xué),可以參考一下,當(dāng)然任何開(kāi)發(fā)人員如果感興趣turbine的設(shè)計(jì),都?xì)g迎。
turbine是什么?
turbine是一個(gè)應(yīng)用開(kāi)發(fā)框架,是一個(gè)開(kāi)發(fā)web應(yīng)用的工具箱,100%純java,且基于jdk1.3及以上。j2ee兼容且基于servlet,面向MVC構(gòu)建。
turbine的框架架構(gòu)overview如下:
turbine的代碼結(jié)構(gòu)包含了services、modules和util幾個(gè)大類(lèi),在上圖中可見(jiàn),在servlet基礎(chǔ)之上,以MVC為基礎(chǔ)結(jié)構(gòu),modules包含了view部分及action,view主要是pages,其中有三種具體的module——screen、layout和navigation,action作為controller存在,toolbox提供了很多通用的tool,service則是整個(gè)框架的插件。一個(gè)完整的請(qǐng)求處理流程如下:
請(qǐng)求到來(lái),turbine的controller處理,view部分渲染頁(yè)面,然后響應(yīng)輸出。
就順著這個(gè)流程,分析一下turbine的架構(gòu),對(duì)于view部分,我們最直觀想到的就是pages,page模塊值包含了幾個(gè)概念,是jsp的?還是velocity的??jī)H此而已。那么,以一個(gè)velocity頁(yè)面為例,如何組織呢?turbine講究的是“約定勝于配置”,記住這句真言,也就可以理解turbine了。在開(kāi)發(fā)應(yīng)用中,要建立三個(gè)頁(yè)面目錄,分別是screen、layout和navigation,screen是頁(yè)面的主體內(nèi)容,layout是頁(yè)面的布局,而navigation則是一些頁(yè)面修飾元素,比如下面這個(gè)頁(yè)面結(jié)構(gòu):
這三個(gè)部分的調(diào)用順序如下:
因?yàn)榧s定的代碼結(jié)構(gòu)是在三個(gè)目錄下寫(xiě)對(duì)應(yīng)名字的java代碼,因此名字如果不一致,那么就會(huì)出錯(cuò)。當(dāng)然,頁(yè)面模板目錄有默認(rèn)的結(jié)構(gòu),如果在對(duì)應(yīng)的目錄下找不到文件,就會(huì)讀取default.vm文件。
類(lèi)似servlet,寫(xiě)一個(gè)java文件對(duì)應(yīng)處理screen頁(yè)面,那么代碼可能是這樣的:
可以看到,這種處理代碼很像servlet,方法就像是servlet標(biāo)準(zhǔn)中的doGet和doPost,只不過(guò)參數(shù)進(jìn)行了封裝。其實(shí),turbine就是一個(gè)servlet,看看turbine的源碼,Turbine類(lèi)繼承了HttpServlet,實(shí)現(xiàn)了doGet和doPost方法,除了一開(kāi)始初始化一系列配置相關(guān)的變量外,在接到一個(gè)http請(qǐng)求(get)后,turbine會(huì)執(zhí)行doGet方法,turbine封裝了request和response,構(gòu)建了一個(gè)叫做RunData的對(duì)象,Rundata是個(gè)接口,具體實(shí)現(xiàn)是DefaultTurbineRunData,其內(nèi)部提供了獲取http各種數(shù)據(jù)的方法接口。在每個(gè)請(qǐng)求周期,turbine都會(huì)利用TurbineRunDataService新建一個(gè)RunData,將所有基于servlet的請(qǐng)求相關(guān)的東西塞到這個(gè)data中。然后,利用從request中得到的請(qǐng)求地址,再調(diào)用PageLoader找到對(duì)應(yīng)的Page,執(zhí)行其中的build方法,其中DefaultPage里會(huì)通過(guò)LayoutLoader和ScreenLoader來(lái)定位到對(duì)應(yīng)的layout和screen,然后執(zhí)行其中的build相關(guān)方法。這樣,一整套請(qǐng)求執(zhí)行就完成了。值得說(shuō)明的就是如果是表單提交,那么多數(shù)情況會(huì)多出一個(gè)action的執(zhí)行,也是在page里進(jìn)行的。如下圖
至于turbine中的tool,這類(lèi)工具是通過(guò)配置,以“拉”模式被應(yīng)用的。當(dāng)應(yīng)用啟動(dòng)后,在vm頁(yè)面中以$開(kāi)始調(diào)用某個(gè)tool的時(shí)候,就會(huì)初始化這個(gè)tool。當(dāng)然,這里就用到了TurbinePullService。
在初步了解了turbine后,如果使用過(guò)webx,那么就會(huì)知道并一定程度理解了webx的設(shè)計(jì);沒(méi)使用過(guò)的,結(jié)合自己用過(guò)的mvc框架,也可以了解一些框架設(shè)計(jì)的思路。
參考資料:
Turbine Tutorial
Apache Turbine
本文全部圖片都截取自Turbine Tutorial,使用請(qǐng)注明