|
Struts2是一套非常優(yōu)秀的Web應(yīng)用框架,實現(xiàn)優(yōu)雅、功能強(qiáng)大、使用簡潔??梢哉f是Struts2是一款非常成熟的MVC架構(gòu)。 在我們學(xué)習(xí)Struts2時,最好是先學(xué)習(xí)它的運行流程、核心概念,從中得到啟發(fā),提升自己,而不僅僅是學(xué)習(xí)怎么怎么使用它。 在網(wǎng)上看到這樣一句話: 你千萬不要成為一個只會熟練使用框架的程序員,那樣,你會疲于奔命,你也許永遠(yuǎn)只會使用 Hadoop ,而寫不出一個 Hadoop ,你只是一個 Hadoop程序員,而不是一個分布式工程師。 一、系統(tǒng)架構(gòu) Struts2的官方文檔附帶了Struts2的架構(gòu)圖。從這張圖可以很好的去理解Struts2
關(guān)于圖中的Key:
1.當(dāng)用戶的發(fā)出請求,比如http:localhost:8080/Struts2/helloworld/helloworldAction.action,請求會被Tomcat接收到,Tomcat服務(wù)器來選擇處理這個請求的Web應(yīng)用,那就是由helloworld這個web工程來處理這個請求。
2.Web容器會去讀取helloworld這個工程的web.xml,在web.xml中進(jìn)行匹配,但發(fā)現(xiàn),由struts2這個過濾器來進(jìn)行處理(也就是
StrutsPrepareAndExecuteFilter),根據(jù)Filter的配置,找到FilterDispatcher(Struts2的調(diào)度中心)
3.然后會獲取FilterDispatcher實例,然后回調(diào)doFilter方法,進(jìn)行真正的處理
PS:FilterDispatcher是任何一個Struts2應(yīng)用都需要配置的,通常情況下,web.xml文件中還有其他過濾器時,F(xiàn)ilterDispatcher是放在濾器鏈的最后;如果在FilterDispatcher前出現(xiàn)了如SiteMesh這種特殊的過濾器,還必須在SiteMesh前引用Struts2的ActionContextCleanUp過濾器
對應(yīng)Struts2的架構(gòu)圖如下
4.這時FilterDispatcher會將請求轉(zhuǎn)發(fā)給ActionMapper。ActionMapper負(fù)責(zé)識別當(dāng)前的請求是否需要Struts2做出處理。ActionMapper就類似于公司的保安,來識別是不是當(dāng)前客戶是不是我公司的人
對應(yīng)Struts2的架構(gòu)圖如下
5.如果需要Struts2處理,ActionMapper會通知FilterDispatcher,需要處理這個請求,F(xiàn)ilterDispatcher會停止過濾器鏈以后的部分,(這也就是為什么,F(xiàn)ilterDispatcher應(yīng)該出現(xiàn)在過濾器鏈的最后的原因)。然后建立一個ActionProxy實例,這個對象作為Action與xwork之間的中間層,會代理Action的運行過程。
對應(yīng)Struts2的架構(gòu)圖如下
6.ActionProxy對象在被創(chuàng)建出來的時候,并不知道要運行哪個Action,它手里只有從FilterDispatcher中拿到的請求的URL。
而真正知道要運行哪個Action的是ConfigurationManager。因為只有它才能讀取我們的strtus.xml
(在服務(wù)器啟動的時候,ConfigurationManager就會把struts.xml中的所有信息讀到內(nèi)存里,并緩存,當(dāng)ActionProxy帶著URL向他詢問要運行哪個Action的時候,就可以直接匹配、查找并回答了)
對應(yīng)Struts2的架構(gòu)圖如下
7.ActionProxy知道自己該干什么事之后(運行哪個Action、相關(guān)的攔截器以及所有可能使用的result信息),然后馬上建立ActionInvocation對象了,ActionInvocation對象描述了Action運行的整個過程。
注意:Action完整的調(diào)用過程都是由ActionInvocation對象負(fù)責(zé) 對應(yīng)Struts2的架構(gòu)圖如下
8.在execute方法之前,好像URL請求中的參數(shù)已經(jīng)賦值到了Action的屬性上,這就是我們的"雷鋒"—攔截器。
攔截器的運行被分成兩部分,一部分在Action之前運行,一部分在Result之后運行,而且順序是剛好反過來的。也就是在Action執(zhí)行前的順序,比如是攔截器1、攔截器2、攔截器3,那么運行Result之后,再次運行攔截器的時候,順序就變成攔截器3、攔截器2、攔截器1了。 這就好比,你要去奶奶家,需要通過 水泊梁山->盤絲洞 -> 索馬里,到了奶奶家,看奶奶回來的時候,就必須要通過 索馬里 -> 盤絲洞 -> 水泊梁山。 所以ActionInvocation對象執(zhí)行的時候需要通過很多復(fù)雜的過程,按照指定攔截器的順序依次執(zhí)行。
對應(yīng)Struts2的架構(gòu)圖如下
9.到了奶奶家,然后執(zhí)行Action的execute方法
10.然后根據(jù)execute方法返回的結(jié)果(Result),去struts.xml中匹配選擇下一個頁面
11.根據(jù)結(jié)果(Result)找到頁面后,在頁面上(有很多Struts2提供的模板),可以通過Struts2自帶的標(biāo)簽庫來訪問需要的數(shù)據(jù),并生成最終頁面 注意:這時還沒有給客戶端應(yīng)答,只是生成了頁面
12.最后,ActionInvocation對象倒序執(zhí)行攔截器,從奶奶家回來
13.ActionInvocation對象執(zhí)行完畢后,已經(jīng)得到響應(yīng)對象(HttpServletResponse)了,最后按與過濾器(Filter)配置定義相反的順序依次經(jīng)過過濾器,向客戶端展示出響應(yīng)的結(jié)果
得到完整Struts2架構(gòu)圖
|
|
|