Gay Bird

          登高者必自卑,行遠(yuǎn)者必自邇,在這個世界上,重要的不是你正站在那里,而是你正朝什么方向移動......

          編程經(jīng)驗(yàn)系列-Java學(xué)習(xí)雜談(九)--Struts2

           最近業(yè)余時間筆者一直Java       Virtual       Machine的研究,由于實(shí)習(xí)分配到項(xiàng)目組里面,不想從前那么閑了,好不容易才抽出時間來繼續(xù)這個話題的帖子。我打算把J2ee的部分結(jié)束之后,再談?wù)?JVM和JavaScript,只要筆者有最新的學(xué)習(xí)筆記總結(jié)出來,一定會拿來及時和大家分享的。衷心希望與熱愛Java的關(guān)大同仁共同進(jìn)步……

              這次準(zhǔn)備繼續(xù)上次的話題先講講Struts-2,手下簡短回顧一段歷史:隨著時間的推移,Web應(yīng)用框架經(jīng)常變化的需求,產(chǎn)生了幾個下一代       Struts的解決方案。其中的Struts       Ti       繼續(xù)堅(jiān)持       MVC模式的基礎(chǔ)上改進(jìn),繼續(xù)Struts的成功經(jīng)驗(yàn)。       WebWork項(xiàng)目是在2002年3月發(fā)布的,它對Struts式框架進(jìn)行了革命性改進(jìn),引進(jìn)了不少新的思想,概念和功能,但和原Struts代碼并不兼       容。WebWork是一個成熟的框架,經(jīng)過了好幾次重大的改進(jìn)與發(fā)布。在2005年12月,WebWork與Struts       Ti決定合拼,       再此同時,       Struts       Ti       改名為       Struts       Action       Framework       2.0,成為Struts真正的下一代。

              看看Struts-2的處理流程:

              1)   Browser產(chǎn)生一個請求并提交框架來處理:根據(jù)配置決定使用哪些攔截器、action類和結(jié)果等。

              2)   請求經(jīng)過一系列攔截器:根據(jù)請求的級別不同攔截器做不同的處理。這和Struts-1的RequestProcessor類很相似。

              3)   調(diào)用Action:       產(chǎn)生一個新的action實(shí)例,調(diào)用業(yè)務(wù)邏輯方法。

              4)   調(diào)用產(chǎn)生結(jié)果:匹配result       class并調(diào)用產(chǎn)生實(shí)例。

              5)   請求再次經(jīng)過一系列攔截器返回:過程也可配置減少攔截器數(shù)量

              6)   請求返回用戶:從control返回servlet,生成Html.

              這里很明顯的一點(diǎn)是不存在FormBean的作用域封裝,直接可以從Action中取得數(shù)據(jù)。       這里有一個Strut-2配置的web.xml文件:

              <filter>

              <filter-name>   controller   </filter-name>

              <filter-class>   org.apache.struts.action2.dispatcher.FilterDispatcher   </filter-class>

              </filter>

              <filter-mapping>

              <filter-name>   cotroller   </filter-name>

              <url-pattern>   /*   </url-pattern>

              </filter-mapping>

              注意到以往的servlet變成了filter,ActionServlet變成了FilterDispatcher,*.do變成了/*.filter 配置定義了名稱(供關(guān)聯(lián))和filter的類。filter       mapping讓URI匹配成功的的請求調(diào)用該filter.默認(rèn)情況下,擴(kuò)展名為   ".action   ".這個是在default.properties文件里的   "struts.action.extension   "屬性定義的。

              default.properties是屬性定義文件,通過在項(xiàng)目classpath路徑中包含一個名為“struts.properties”的文件來設(shè)置不同的屬性值。而Struts-2的默認(rèn)配置文件名為struts.xml.由于1和2的action擴(kuò)展名分別為。do和。action,所以很方便能共存。我們再來看一個Struts-2的action代碼:

              public   class   MyAction   {

              public   String   execute()   throws   Exception   {

              //do   the   work return   "success   ";

              }

              }
             很明顯的區(qū)別是不用再繼承任何類和接口,返回的只是一個String,無參數(shù)。實(shí)際上在Struts-2中任何返回String的無參數(shù)方法都可以通過配置來調(diào)用action.所有的參數(shù)從哪里來獲得呢?答案就是Inversion       of       Control技術(shù)(控制反轉(zhuǎn))。筆者盡量以最通俗的方式來解釋,我們先試圖讓這個Action獲得reuqest對象,這樣可以提取頁面提交的任何參數(shù)。那么我們把request設(shè)為一個成員變量,然后需要一個對它的set方法。由于大部分的action都需要這么做,我們把這個set方法作為接口來實(shí)現(xiàn)。

              public   interface   ServletRequestAware   {

              public   void   setServletRequest(HttpServletRequest   request);

              }

              public   class   MyAction   implements   ServletRequestAware   {

              private   HttpServletRequest   request;

              public   void   setServletRequest(HttpServletRequest   request)   {

              this.request   =   request;

              }

              public   String   execute()   throws   Exception       {

              //     do   the   work   directly   using   the   request

              return       Action.SUCCESS;

              }

              }

              那么誰來調(diào)用這個set方法呢?也就是說誰來控制這個action的行為,以往我們都是自己在適當(dāng)?shù)牡胤綄懮弦痪?action.setServletRequest(…),也就是控制權(quán)在程序員這邊。然而控制反轉(zhuǎn)的思想是在哪里調(diào)用交給正在運(yùn)行的容器來決定,只要利用Java反射機(jī)制來獲得Method對象然后調(diào)用它的invoke方法傳入?yún)?shù)就能做到,這樣控制權(quán)就從程序員這邊轉(zhuǎn)移到了容器那邊。程序員可以減輕很多繁瑣的工作更多的關(guān)注業(yè)務(wù)邏輯。Request可以這樣注入到action中,其他任何對象也都可以。為了保證action的成員變量線程安全, Struts-2的action不是單例的,每一個新的請求都會產(chǎn)生一個新的action實(shí)例。

              那么有人會問,到底誰來做這個對象的注入工作呢?答案就是攔截器。攔截器又是什么東西?筆者再來盡量通俗的解釋攔截器的概念。大家要理解攔截器的話,首先一定要理解GOF23種設(shè)計(jì)模式中的Proxy模式。

              A對象要調(diào)用f(),它希望代理給B來做,那么B就要獲得A對象的引用,然后在B的f()中通過A對象引用調(diào)用A對象的f()方法,最終達(dá)到A的f()被調(diào)用的目的。有沒有人會覺得這樣很麻煩,為什么明明只要A.f()就可以完成的一定要封裝到B的f()方法中去?有哪些好處呢?

              1)   這里我們只有一個A,當(dāng)我們有很多個A的時候,只需要監(jiān)視B一個對象的f()方法就可以從全局上控制所有被調(diào)用的f()方法。

              2)   另外,既然代理人B能獲得A對象的引用,那么B可以決定在真正調(diào)A對象的f()方法之前可以做哪些前置工作,調(diào)完返回前可有做哪些后置工作。

              講到這里,大家看出來一點(diǎn)攔截器的概念了么?它攔截下一調(diào)f()方法的請求,然后統(tǒng)一的做處理(處理每個的方式還可以不同,解析A對象就可以辨別),處理完畢再放行。這樣像不像對流動的河水橫切了一刀,對所有想通過的水分子進(jìn)行搜身,然后再放行?這也就是AOP(Aspect       of       Programming面向切面編程)的思想。

              Anyway,Struts-2只是利用了AOP和IoC技術(shù)來減輕action和框架的耦合關(guān)系,力圖到最大程度重用action的目的。在這樣的技術(shù)促動下,Struts-2的action成了一個簡單被框架使用的POJO(Plain       Old       Java       Object)罷了。實(shí)事上AOP和IoC的思想已經(jīng)遍布新出來的每一個框架上,他們并不是多么新的技術(shù),利用的也都是JDK早已可以最到的事情,它們代表的是更加面向接口編程,提高重用,增加擴(kuò)展性的一種思想。Struts-2只是部分的使用這兩種思想來設(shè)計(jì)完成的,另外一個最近很火的框架 Spring,更大程度上代表了這兩種設(shè)計(jì)思想,筆者將于下一篇來進(jìn)一步探討Spring的結(jié)構(gòu)。

          posted on 2008-09-12 17:24 Sky Yi 閱讀(179) 評論(0)  編輯  收藏 所屬分類: 編程經(jīng)驗(yàn)系列-Java學(xué)習(xí)雜談(轉(zhuǎn))

          主站蜘蛛池模板: 静乐县| 合水县| 牡丹江市| 金门县| 全南县| 鄂托克旗| 平定县| 保康县| 乌鲁木齐县| 佛教| 西乌| 丰原市| 鲜城| 特克斯县| 来安县| 集贤县| 东港市| 平陆县| 根河市| 水富县| 云梦县| 诸暨市| 留坝县| 新乡市| 北安市| 拉萨市| 新沂市| 称多县| 连江县| 沙坪坝区| 巴彦县| 焦作市| 白水县| 绥中县| 兴文县| 勐海县| 麻阳| 博野县| 台安县| 临沭县| 嘉祥县|