1. 程式人生 > >走進Struts2(一) — Struts2的執行流程及其工作原理

走進Struts2(一) — Struts2的執行流程及其工作原理

管理 npr clean 核心部分 由於 nco 方式 中間 con

Struts2是一套很優秀的Web應用框架,實現優雅、功能強大、使用簡潔。能夠說是Struts2是一款很成熟的MVC架構。

在我們學習Struts2時,最好是先學習它的執行流程、核心概念。從中得到啟示。提升自己,而不不過學習怎麽怎麽使用它。

在網上看到這樣一句話:

你千萬不要成為一個僅僅會熟練使用框架的程序猿。那樣。你會疲於奔命,你或許永遠僅僅會使用 Hadoop ,而寫不出一個 Hadoop ,你僅僅是一個 Hadoop程序猿,而不是一個分布式project師。


你或許永遠僅僅會使用 Struts,而忘記了自己寫 filter,你僅僅是一個 SSH 程序猿,而不是一個 Web project師。


話不多說,一起走進Struts2

一、系統架構

Struts2的官方文檔附帶了Struts2的架構圖。

從這張圖能夠非常好的去理解Struts2

技術分享

關於圖中的Key:

  • Servlet Filters:過濾器鏈,client的全部請求都要經過Filter鏈的處理。
  • Struts Core:Struts2的核心部分,可是Struts2已經幫我們做好了,我們不須要去做這個
  • Interceptors。Struts2的攔截器。Struts2提供了非常多默認的攔截器。能夠完畢日常開發的絕大部分工作;而我們自己定義的攔截器,用來實現實際的客戶業務須要的功能。
  • User Created,由開發者創建的。包含struts.xml、Action、Template。這些是每一個使用Struts2來進行開發的人員都必須會的。


  • 1.FilterDispatcher是整個Struts2的調度中心。也就是MVC中的C(控制中心),依據ActionMapper的結果來決定是否處理請求,假設ActionMapper指出該URL應該被Struts2處理。那麽它將會運行Action處理,並停止過濾器鏈上還沒有運行的過濾器。
  • 2.ActionMapper 會推斷這個請求是否應該被Struts2處理,假設須要Struts2處理。ActionMapper會返回一個對象來描寫敘述請求相應的ActionInvocation的信息。

  • 3.ActionProxy。它會創建一個ActionInvocation實例,位於Action和xwork之間,使得我們在將來有機會引入很多其它的實現方式。比方通過WebService來實現等。
  • 4.ConfigurationManager是xwork配置的管理中心,能夠把它看做struts.xml這個配置文件在內存中的相應。
  • 5.struts.xml,是開發人員必須光顧的地方。是Stuts2的應用配置文件,負責諸如URL與Action之間映射關系的配置、以及運行後頁面跳轉的Result配置等。
  • 6.ActionInvocation:真正調用並運行Action,它擁有一個Action實例和這個Action所依賴的攔截器實例。ActionInvocation會依照指定的順序去運行這些攔截器、Action以及相應的Result。

  • Interceptor(攔截器):是Struts2的基石。類似於JavaWeb的Filter,攔截器是一些無狀態的類。攔截器能夠自己主動攔截Action,它們給開發人員提供了在Action運行之前或Result運行之後來運行一些功能代碼的機會。
  • 7.Action:用來處理請求,封裝數據。


  • 二、執行流程

1.當用戶的發出請求。比方http:localhost:8080/Struts2/helloworld/helloworldAction.action,請求會被Tomcat接收到,Tomcatserver來選擇處理這個請求的Web應用,那就是由helloworld這個webproject來處理這個請求。 2.Web容器會去讀取helloworld這個project的web.xml。在web.xml中進行匹配,但發現,由struts2這個過濾器來進行處理(也就是 StrutsPrepareAndExecuteFilter)。依據Filter的配置,找到FilterDispatcher(Struts2的調度中心 3.然後會獲取FilterDispatcher實例,然後回調doFilter方法,進行真正的處理 PS:FilterDispatcher是不論什麽一個Struts2應用都須要配置的,通常情況下。web.xml文件裏還有其它過濾器時,FilterDispatcher是放在濾器鏈的最後;假設在FilterDispatcher前出現了如SiteMesh這樣的特殊的過濾器,還必須在SiteMesh前引用Struts2的ActionContextCleanUp過濾器
相應Struts2的架構圖例如以下
技術分享

4.這時FilterDispatcher會將請求轉發給ActionMapperActionMapper負責識別當前的請求是否須要Struts2做出處理。ActionMapper就類似於公司的保安。來識別是不是當前客戶是不是我公司的人
相應Struts2的架構圖例如以下

技術分享

5.假設須要Struts2處理。ActionMapper會通知FilterDispatcher。須要處理這個請求。FilterDispatcher會停止過濾器鏈以後的部分,(這也就是為什麽,FilterDispatcher應該出如今過濾器鏈的最後的原因)。然後建立一個ActionProxy實例。這個對象作為Action與xwork之間的中間層。會代理Action的執行過程。

相應Struts2的架構圖例如以下

技術分享

6.ActionProxy對象在被創建出來的時候,並不知道要執行哪個Action,它手裏僅僅有從FilterDispatcher中拿到的請求的URL。 而真正知道要執行哪個Action的是ConfigurationManager。由於僅僅有它才幹讀取我們的strtus.xml
(在server啟動的時候,ConfigurationManager就會把struts.xml中的全部信息讀到內存裏,並緩存。當ActionProxy帶著URL向他詢問要執行哪個Action的時候,就能夠直接匹配、查找並回答了)

相應Struts2的架構圖例如以下

技術分享 -> 技術分享

7.ActionProxy知道自己該幹什麽事之後(執行哪個Action、相關的攔截器以及全部可能使用的result信息),然後立即建立ActionInvocation對象了,ActionInvocation對象描寫敘述了Action執行的整個過程。

註意:Action完整的調用過程都是由ActionInvocation對象負責


相應Struts2的架構圖例如以下

技術分享


8.在execute方法之前,好像URL請求中的參數已經賦值到了Action的屬性上。這就是我們的"雷鋒"—攔截器。

攔截器的執行被分成兩部分,一部分在Action之前執行,一部分在Result之後執行,並且順序是剛好反過來的。也就是在Action執行前的順序,比方是攔截器1、攔截器2、攔截器3,那麽執行Result之後,再次執行攔截器的時候,順序就變成攔截器3、攔截器2、攔截器1了。

這就好比,你要去奶奶家。需要通過 水泊梁山->盤絲洞 -> 索馬裏,到了奶奶家。看奶奶回來的時候,就必需要通過 索馬裏 -> 盤絲洞 -> 水泊梁山。

所以ActionInvocation對象運行的時候須要通過非常多復雜的過程,依照指定攔截器的順序依次運行。


相應Struts2的架構圖例如以下


技術分享



9.到了奶奶家,然後運行Action的execute方法



技術分享


10.然後依據execute方法返回的結果(Result),去struts.xml中匹配選擇下一個頁面


技術分享


11.依據結果(Result)找到頁面後,在頁面上(有非常多Struts2提供的模板),能夠通過Struts2自帶的標簽庫來訪問須要的數據,並生成終於頁面

註意:這時還沒有給client應答,僅僅是生成了頁面


技術分享


12.最後,ActionInvocation對象倒序運行攔截器,從奶奶家回來


技術分享


13.ActionInvocation對象運行完成後,已經得到響應對象(HttpServletResponse)了,最後按與過濾器(Filter)配置定義相反的順序依次經過過濾器,向client展示出響應的結果


得到完整Struts2架構圖


技術分享





走進Struts2(一) — Struts2的執行流程及其工作原理