Struts2是一套很是優秀的Web應用框架,實現優雅、功能強大、使用簡潔。能夠說是Struts2是一款很是成熟的MVC架構。程序員
在咱們學習Struts2時,最好是先學習它的運行流程、核心概念,從中獲得啓發,提高本身,而不只僅是學習怎麼怎麼使用它。web
在網上看到這樣一句話:緩存
你千萬不要成爲一個只會熟練使用框架的程序員,那樣,你會疲於奔命,你也許永遠只會使用 Hadoop ,而寫不出一個 Hadoop ,你只是一個 Hadoop程序員,而不是一個分佈式工程師。
你也許永遠只會使用 Struts,而忘記了本身寫 filter,你只是一個 SSH 程序員,而不是一個 Web 工程師。
話很少說,一塊兒走進Struts2服務器
1、系統架構架構
Struts2的官方文檔附帶了Struts2的架構圖。從這張圖能夠很好的去理解Struts2app
關於圖中的Key:框架
1.當用戶的發出請求,好比http:localhost:8080/Struts2/helloworld/helloworldAction.action,請求會被Tomcat接收到,Tomcat服務器來選擇處理這個請求的Web應用,那就是由helloworld這個web工程來處理這個請求。分佈式
2.Web容器會去讀取helloworld這個工程的web.xml,在web.xml中進行匹配,但發現,由struts2這個過濾器來進行處理(也就是oop
StrutsPrepareAndExecuteFilter),根據Filter的配置,找到FilterDispatcher(Struts2的調度中心)學習
3.而後會獲取FilterDispatcher實例,而後回調doFilter方法,進行真正的處理
PS:FilterDispatcher是任何一個Struts2應用都須要配置的,一般狀況下,web.xml文件中還有其餘過濾器時,FilterDispatcher是放在濾器鏈的最後;若是在FilterDispatcher前出現瞭如SiteMesh這種特殊的過濾器,還必須在SiteMesh前引用Struts2的ActionContextCleanUp過濾器
對應Struts2的架構圖以下
4.這時FilterDispatcher會將請求轉發給ActionMapper。ActionMapper負責識別當前的請求是否須要Struts2作出處理。ActionMapper就相似於公司的保安,來識別是否是當前客戶是否是我公司的人
對應Struts2的架構圖以下
5.若是須要Struts2處理,ActionMapper會通知FilterDispatcher,須要處理這個請求,FilterDispatcher會中止過濾器鏈之後的部分,(這也就是爲何,FilterDispatcher應該出如今過濾器鏈的最後的緣由)。而後創建一個ActionProxy實例,這個對象做爲Action與xwork之間的中間層,會代理Action的運行過程。
對應Struts2的架構圖以下
6.ActionProxy對象在被建立出來的時候,並不知道要運行哪一個Action,它手裏只有從FilterDispatcher中拿到的請求的URL。
而真正知道要運行哪一個Action的是ConfigurationManager。由於只有它才能讀取咱們的strtus.xml
(在服務器啓動的時候,ConfigurationManager就會把struts.xml中的全部信息讀到內存裏,並緩存,當ActionProxy帶着URL向他詢問要運行哪一個Action的時候,就能夠直接匹配、查找並回答了)
對應Struts2的架構圖以下
->
7.ActionProxy知道本身該幹什麼事以後(運行哪一個Action、相關的攔截器以及全部可能使用的result信息),而後立刻創建ActionInvocation對象了,ActionInvocation對象描述了Action運行的整個過程。
注意:Action完整的調用過程都是由ActionInvocation對象負責
對應Struts2的架構圖以下
8.在execute方法以前,好像URL請求中的參數已經賦值到了Action的屬性上,這就是咱們的"雷鋒"—攔截器。
攔截器的運行被分紅兩部分,一部分在Action以前運行,一部分在Result以後運行,並且順序是恰好反過來的。也就是在Action執行前的順序,好比是攔截器一、攔截器二、攔截器3,那麼運行Result以後,再次運行攔截器的時候,順序就變成攔截器三、攔截器二、攔截器1了。
這就比如,你要去奶奶家,須要經過 水泊梁山->盤絲洞 -> 索馬里,到了奶奶家,看奶奶回來的時候,就必需要經過 索馬里 -> 盤絲洞 -> 水泊梁山。
因此ActionInvocation對象執行的時候須要經過不少複雜的過程,按照指定攔截器的順序依次執行。
對應Struts2的架構圖以下
9.到了奶奶家,而後執行Action的execute方法
10.而後根據execute方法返回的結果(Result),去struts.xml中匹配選擇下一個頁面
11.根據結果(Result)找到頁面後,在頁面上(有不少Struts2提供的模板),能夠經過Struts2自帶的標籤庫來訪問須要的數據,並生成最終頁面
注意:這時尚未給客戶端應答,只是生成了頁面
12.最後,ActionInvocation對象倒序執行攔截器,從奶奶家回來
13.ActionInvocation對象執行完畢後,已經獲得響應對象(HttpServletResponse)了,最後按與過濾器(Filter)配置定義相反的順序依次通過過濾器,向客戶端展現出響應的結果
獲得完整Struts2架構圖