<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    beauty_beast

    上善若水 厚德載物

    學習設計模式之proxy模式

    Posted on 2005-08-19 16:58 柳隨風 閱讀(934) 評論(0)  編輯  收藏 所屬分類: java基礎

    前言: 本文只是本人的學習總結,目的希望能和大家一起交流分享,順便備忘,如有不正確的地方,歡迎指正。本文可能需要你對webwork框架有一定的了解。

     

    我們在開發中Proxy模式是經常用到的,代理主要用來對訪問的資源進行權限控制以及監控的目的,如果我們在開發系統需要對訪問的對象進行控制和監控的話,proxy模式是很有用途的。

    舉些例子:

    我們開發一個應用系統時,用戶請求任何頁面都要經過權限控制,最早開發的時候我們常常封裝一個權限驗證方法,然后在每個jsp或者對應的servlet中增加相關代碼,但是用戶對權限的需求往往是多變的,這樣一旦權限驗證方法變化(參數變化,增加方法),如果開發的系統很龐大的話,有可能你就需要修改幾百個jsp頁面或者servlet代碼。

    還有我們常需要判斷session是否過期,如果過期就要重新登陸系統,如果每個頁面或者servlet都要加判斷代碼,那也是件比較痛苦的事情。

    如果我們采用代理模式,增加Proxy對象,每次用戶請求必須通過proxy對象處理,由它專門處理相關權限控制,一旦權限需求變化了,只需要修改Proxy對象相關的實現方法。

    Proxy模式不僅僅用于上述場景,還可以在其他方面應用。

     

    我們可以研究研究webwork的源代碼,看看它是如何設計的。

     

    webwork開發框架目前是比較流行的web開發框架之一,最近我的開發項目就采用了該框架,它相比struts有很多優點(晚出來的再沒優點也不行啊,呵呵,關于其缺點也有,有時間再說),

    主要如下:

    1、    易單元測試;

    2、    線程安全;

    3、    允許使用截取器模塊化前/后處理. 攔截器可以通過配置動態添加, 兩者之間沒有任何耦合;

    4、    WebWork 2使用Ognl, 強大的表達式語言, 也可以訪問值棧. Ognl對集合和索引屬性的支持非常強大。

    其中優點3的實現和proxy模式是非常相關的,下面就講講webwork如何采用Proxy模式實現其優點3的。

     

    首先我們看看webwork的核心類ServletDispatcher的請求處理代碼:

    public void serviceAction(
    HttpServletRequest request, HttpServletResponse response, 
    String 
    namespace, String actionName, 
    Map requestMap, Map parameterMap, 
    Map sessionMap, Map applicationMap) 
    {
    HashMap extraContext 
    = createContextMap(requestMap, parameterMap, sessionMap, applicationMap, request, response, getServletConfig());
    extraContext.put(SERVLET_DISPATCHER, 
    this);
    try {
        ActionProxy proxy 
    =   ActionProxyFactory.getFactory).
    createActionProxy(
    namespace, actionName, extraContext);
       request.setAttribute(
    "webwork.valueStack", proxy.getInvocation().getStack());
       proxy.execute();
    }

    catch (ConfigurationException e) {
       log.error(
    "Could not find action", e);
       sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e);
           }

    catch (Exception e) {
       log.error(
    "Could not execute action", e);
       sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e);
    }

    }


    .可以看到整個對請求的處理非常簡練:通過工廠方法獲取一個ActionProxy 實例,執行ActionProxy實例的execute()方法,所有請求都需要通過該方法處理。

    ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext);

    這段代碼調用過程我簡單描述一下:

        首先ActionProxyFactory.getFactory().獲取到一個DefaultActionProxyFactory實例,然后該工廠實例調用createActionProxy(相關參數)方法創建一個DefaultActionProxy示例。
     

    下面我們看看這個DefaultActionProxy究竟是如何處理的:

    首先它會根據相關信息獲取當前Action配置對象,從中可以知道當前Action中配置了那些攔截器、Result等等配置信息,具體可以查看ActionConfig對象,然后創建一個調用對象DefaultActionInvocation實例(也是通過工廠方法),該實例調用invoke()方法完成該action配置的攔截器的攔截方法以及actionexecute()方法或action自定義的method的執行。

    public String invoke() throws Exception {
            
    if (executed) {
                
    throw new IllegalStateException("Action has already executed");
            }

            
    if (interceptors.hasNext()) {
                Interceptor interceptor 
    = (Interceptor) interceptors.next();
                resultCode 
    = interceptor.intercept(this);
            }
     else {
                
    if (proxy.getConfig().getMethodName() == null{
                    resultCode 
    = getAction().execute();
                }
     else {
                    resultCode 
    = invokeAction(getAction(), proxy.getConfig());
                }

            }

            
    // this is needed because the result will be executed, then control will return to the Interceptor, which will
            
    // return above and flow through again
            if (!executed) {
                
    if (preResultListeners != null{
                    
    for (Iterator iterator = preResultListeners.iterator();
                            iterator.hasNext();) 
    {
                        PreResultListener listener 
    = (PreResultListener) iterator.next();
                        listener.beforeResult(
    this, resultCode);
                    }

                }


                
    // now execute the result, if we're supposed to
                if (proxy.getExecuteResult()) {
                    executeResult();
                }

                executed 
    = true;
            }

            
    return resultCode;
        }

    而一般攔截器對象都是AroundInterceptor的子類,在AroundInterceptor類中的攔截方法如下:

       public String intercept(ActionInvocation invocation) throws Exception {
            String result 
    = null;
            before(invocation);
            result 
    = invocation.invoke();
            after(invocation, result);
            
    return result;
        }

     

    注意該調用對象的invoke方法比較有意思,它采用的是遍歷調用的方式,每個Action一般都有多個攔截器,每個攔截器執行完畢后再回調該調用對象的invoke方法,有點像鏈式,如果中間有自定義攔截器有發現異常,不要再執行下去,直接返回Result相關字符串,中斷之后的攔截器以及Action不再執行,正常情況下鏈尾是調用對應Action實例的execute()方法,獲取Result相關字符串后,根據字符串值獲取相關Result實例,執行Result實例中excute()方法派發或者重導向到相關視圖(jspvm等等),一旦鏈尾處理過請求后,鏈中的其他節點就不需要再派發。只需繼續執行攔截器中的after()方法(如果有的話)的執行,webwork采用這樣的方式實現主要是為了滿足action后處理功能的需要(有點跑題了,變成webwork框架源碼分析)

    題外話:從整個調用過程我們可以發現: Webwork框架的核心功能實際上都是在Xwork框架中實現的,Webwork實際上只是XworkB/S系統上的應用。

     

    結束總結:

    1、我們在開發時,如果要對訪問的對象進行統一預處理、控制、監控管理時可以采用Proxy模式。

    2Proxy模式往往和Factory模式一起使用。個人理解是因為考慮系統的擴展性、通用性,有可能有不同的類型的Proxy以及調用,根據不同的應用場景,可以采用不同的工廠創建。

    3、如果運用的不是很恰當的話,會造成Proxy的實現很龐大,并且和相關對象耦合過高,而webwork采用配置每個action對應的攔截器這種設計就非常好,耦合也比較低,實際上它變相的實現了每個對象采用不同的Proxy,個人感覺其這方面的設計很不錯,可以借鑒。





    主站蜘蛛池模板: 亚洲av纯肉无码精品动漫| 亚洲va在线va天堂va888www| 亚洲精品人成网在线播放影院| 99热精品在线免费观看| 久久久久久亚洲精品| 免费一级毛片在线播放视频| 亚洲AV无码专区国产乱码4SE| 成人片黄网站色大片免费观看APP| 久久精品国产精品亚洲下载| 亚洲精品视频免费观看| 亚洲AV综合色一区二区三区| 2021在线永久免费视频| 亚洲一区中文字幕在线电影网| 精品久久久久久久久免费影院| 国产精品亚洲午夜一区二区三区 | 97在线视频免费| 久久精品国产亚洲AV香蕉| 亚洲人成在线免费观看| 亚洲欧美一区二区三区日产| 免费人妻无码不卡中文字幕18禁 | 九九九国产精品成人免费视频| 国产AⅤ无码专区亚洲AV| 99久久久国产精品免费牛牛四川| 亚洲伊人精品综合在合线| 日本成人在线免费观看| 成人国产精品免费视频| 亚洲大片免费观看| 国产91久久久久久久免费| 久久久精品午夜免费不卡| 亚洲午夜在线一区| 国产一区二区三区免费看| 久久久国产精品福利免费| 亚洲欧美日韩中文无线码| 亚洲欧洲成人精品香蕉网| 成人免费a级毛片| 成人无码精品1区2区3区免费看| 亚洲无限乱码一二三四区| 亚洲成A人片在线观看中文| 91免费福利精品国产| 免费高清A级毛片在线播放| 91亚洲国产成人精品下载|