隨筆 - 63  文章 - 0  trackbacks - 0
          <2009年4月>
          2930311234
          567891011
          12131415161718
          19202122232425
          262728293012
          3456789

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

                 Action類是用戶請求和業務邏輯之間的橋梁,每個Action充當客戶的一項業務代理。在RequestProcessor類預處理請求時,在創建了Action的實例后,就調用自身的processActionPerform()方法,該方法再調用Action類的execute()。
          Action的excute()方法調用模型的業務方法,完成用戶請求,然后根據執行結果把請求轉發給其他合適的WEB組件。

          一、Action類緩存

                struts應用的生命周期中RequestProcessor只保證一個Action實例,所有的客戶請求都共享這個實例.所有請求可以同時執行它的excute()方法。RequestProcessor類包含一個HashMap,作為存放所有Action實例的緩存。每個Action實例在緩存中存放的key為Action類名。在RequestProcessor類的processActionCreate()方法中,首先檢查在HashMap中是否存在Action實例,如果有直接使用,否則創建一個新的。創建Action實力的代碼位于同步代碼塊中,以保證只有一個線程創建Action實例,然后放在HashMap中。供其他線程使用。
          如下代碼
        1. protected Action processActionCreate(HttpServletRequest request,   
        2.                                        HttpServletResponse response,   
        3.                                        ActionMapping mapping)   
        4.       throws IOException 
        5. {   
        6.       // Acquire the Action instance we will be using (if there is one)   
        7.       String className = mapping.getType();   
        8.       if (log.isDebugEnabled()) 
        9.      {   
        10.           log.debug(" Looking for Action instance for class " + className);   
        11.       }   
        12.   
        13.       // :TODO: If there were a mapping property indicating whether   
        14.       // an Action were a singleton or not ([true]),   
        15.       // could we just instantiate and return a new instance here?   
        16.   
        17.       Action instance = null;   
        18.       synchronized (actions) 
        19.      {   
        20.           // Return any existing Action instance of this class   
        21.           instance = (Action) actions.get(className);   
        22.           if (instance != null)
        23.          {   
        24.               if (log.isTraceEnabled()) 
        25.              {   
        26.                   log.trace("  Returning existing Action instance");   
        27.               }   
        28.               return (instance);   
        29.           }   
        30.   
        31.           // Create and return a new Action instance   
        32.           if (log.isTraceEnabled()) 
        33.          {   
        34.               log.trace("  Creating new Action instance");   
        35.           }   
        36.              
        37.           try
        38.          {   
        39.               instance = (Action) RequestUtils.applicationInstance(className);   
        40.               // :TODO: Maybe we should propagate this exception   
        41.               // instead of returning null.   
        42.           } 
        43.           catch (Exception e) 
        44.          {   
        45.               log.error(   
        46.                   getInternal().getMessage("actionCreate", mapping.getPath()),   
        47.                   e);   
        48.                      
        49.               response.sendError(   
        50.                   HttpServletResponse.SC_INTERNAL_SERVER_ERROR,   
        51.                   getInternal().getMessage("actionCreate", mapping.getPath()));                         
        52.               return (null);   
        53.           }         
        54.           instance.setServlet(this.servlet);   
        55.           actions.put(className, instance);   
        56.       }   
        57.   
        58.       return (instance);   
        59.   
        60.   }  

           

          二.創建支持多線程的Action
          1.什么是線程安全的代碼
          在多線程環境下能正確執行的代碼就是線程安全的。
          安全的意思是能正確執行,否則后果是程序執行錯誤,可能出現各種異常情況。

          2.如何編寫線程安全的代碼
          很多書籍里都詳細講解了如何這方面的問題,他們主要講解的是如何同步線程對共享資源的使用的問題。主要是對synchronized關鍵字的各種用法,以及鎖的概念。
          Java1.5中也提供了如讀寫鎖這類的工具類。這些都需要較高的技巧,而且相對難于調試。

          但是,線程同步是不得以的方法,是比較復雜的,而且會帶來性能的損失。等效的代碼中,不需要同步在編寫容易度和性能上會更好些。
          我這里強調的是什么代碼是始終為線程安全的、是不需要同步的。如下:
          1)常量始終是線程安全的,因為只存在讀操作。
          2)對構造器的訪問(new 操作)是線程安全的,因為每次都新建一個實例,不會訪問共享的資源。
          3)最重要的是:局部變量是線程安全的。因為每執行一個方法,都會在獨立的空間創建局部變量,它不是共享的資源。局部變量包括方法的參數變量。

          Servlet是在多線程環境下的。即可能有多個請求發給一個servelt實例,每個請求是一個線程。 struts下的action也類似,同樣在多線程環境下,你也必須編寫線程安全的Action類。
          保證線程安全的原則就是僅僅使用局部變量,謹慎使用實例變量(擁有狀態的實例,尤其是擁有業務對象狀態的實例). 如果要用到那些有狀態的實例,唯一和最好的辦法是在Action類中,僅僅在Action類的execute()方法中使用局部變量,對于每個調用execute()方法的線程,JVM會在每個線程的堆棧中創建局部變量,因此每個線程擁有獨立的局部變量,不會被其他線程共享.當線程執行完execute()方法后,它的局部變量就會被銷毀.
          如果Action類的實例變量是必須的話,需要采用JAVA同步機制(synchronized)對訪問共享資源的代碼塊進行同步


          三、Struts的幾種Action
          Struts提供了一些現成的Action類,直接使用可以大大節省時間,如下
          ForwardAction
          可以轉發到其他web組件,僅僅提供一個轉發功能,不作處理。
          IncludeAction
          包含其他web組件。
          DiapatchAction
          通常一個Action只完成一個操作,用這個Action可以完成一組相關的操作。
          LookupDispatchAction
          他是DiapatchAction的子類,也可以定義多個方法,但主要用于一個表單里有多個按鈕,而這些按鈕又有一個共同的名字的場合。
          SwitchAction
          用于子模塊之間的切換。


          四.ActionForward類
          Action類的excute()方法返回一個ActionForward對象,它代表了web資源的邏輯抽象,這里的web資源可以是jsp頁面、Java servlet、或Action
          從excute返回ActionForward可以有兩種方法。
          1) 動態創建一個ActionForward實例
          return new ActionForward(”Failure”,”login.jsp”,true);
          2) 調用ActionMappin實例的findForward方法
          這個方法先從action級別找,然后在<global-forwards />級別找
          return mapping.findForward(“Failure”);

        61. posted on 2009-04-05 11:19 lanxin1020 閱讀(193) 評論(0)  編輯  收藏 所屬分類: struts1
          主站蜘蛛池模板: 林口县| 泸西县| 清河县| 措勤县| 新巴尔虎右旗| 济阳县| 开阳县| 贵德县| 阳高县| 方山县| 庄浪县| 丰顺县| 台安县| 商都县| 陆河县| 永康市| 张掖市| 璧山县| 滨海县| 云南省| 黑龙江省| 拜城县| 本溪市| 卢氏县| 祥云县| 沙田区| 湖口县| 六盘水市| 紫阳县| 昭苏县| 孟连| 巴林左旗| 建平县| 客服| 二手房| 广宗县| 南木林县| 治多县| 醴陵市| 张家口市| 和平区|