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

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

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

    上善若水
    In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra
    posts - 146,comments - 147,trackbacks - 0

    概述

    在很多框架的設(shè)計中,都有類似Channel鏈的設(shè)計,類似Decorator模式或Chain Of Responsibility模式,可以向這個Channel注冊不同的Handler,用戶請求可以穿越這個由多個Handler組成的Channel,執(zhí)行響應(yīng)的切面邏輯,在最后一個Handler或者另一個Processor處理用于自定義的業(yè)務(wù)邏輯,然后生成的響應(yīng)可以逆著方向從這個Channel回來。Structs2中的Interceptor、Servlet中Filter都采用這種設(shè)計。這種設(shè)計為面向切面編程提供了遍歷,然而目前的Handler設(shè)計更多的像是Chain Of Responsibility模式,它的處理邏輯只能從鏈頭走到鏈尾,而沒有返回的路程。引入ScopedHandler的目的就是用于解決這個問題。

    實現(xiàn)

    Structs2中Interceptor實現(xiàn)使用傳入ActionInvaction來調(diào)用Channel中的后繼Interceptor:
    public class MyInterceptor extends AbstractInterceptor {
        @Override
         public String intercept(ActionInvocation ai) throws Exception {
            try {
                 // Add user customized logic here when request come into the channel
                 return ai.invoke();
            } finally {
                 // Add user customized logic here when response pass out across the channel
            }        
        } 
    }
    類似的,Servlet中的Filter實現(xiàn)也是使用FilterChain來調(diào)用Channel中后繼的Filter:
    public class MyFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            try {
                // Add user customized logic here when request come into the channel
                chain.doFilter(request, response);
            } finally {
                // Add user customized logic here when response pass out across the channel
            }
        }
    }

    ScopedHandler采用了不同的實現(xiàn)方式,首先它繼承自HandlerWrapper,因而它使用HandlerWrapper中的Handler字段來構(gòu)建Handler鏈,然而并不是所有的Handler都是ScopedHandler,因而ScopedHandler內(nèi)部還定義了_nextScope字段用于創(chuàng)建在這條Handler鏈表中的ScopedHandler鏈表,以及_outerScope字段用于將自己始終和這個ScopedHandler鏈表中的最外層ScopedHandler相連,對這個ScopedHandler的最外層列表,其_outScope字段為null。而ScopedHandler要實現(xiàn)的行為是,假設(shè)A、B、C都是ScopedHandler,并且它們組成鏈表:A->B->C,那么當(dāng)調(diào)用A.handle()方法時的調(diào)用堆棧是:
    A.handle()
    |-A.doScope()
    |--B.doScope()
    |----C.doScope()
    |-----A.doHandle()
    |------B.doHandle()
    |-------C.doHandle()
    而如果A、B是ScopedHandler,X、Y是其他的Handler,并且它們組成鏈表:A->X->B->Y,那么當(dāng)調(diào)用A.handle()方法時的調(diào)用棧是:
    A.handle()
    |-A.doScope()
    |--B.doScope()
    |---A.doHandle()
    |----X.handle()
    |-----B.doHandle()
    |------Y.handle()

    這種行為主要用于Servlet框架的實現(xiàn),它可以保證在doScope()方法中做一些初始化工作,并且配置環(huán)境,而在后繼調(diào)用中都可以使用這些配置好的環(huán)境,并且doHandle()的順序還是使用原來定義的Handler鏈表順序,即使有些Handler并不是ScopedHandler。

    在實現(xiàn)中,其Handler鏈表由HandlerWrapper構(gòu)建,在doStart()方法中計算_nextScope字段以及_outerScope字段,在handle()方法中,如果_outerScope為null,則調(diào)用doScope()方法,否則調(diào)用doHandle()方法:
        @Override
        public final void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {
            if (_outerScope==null)  
                doScope(target,baseRequest,request, response);
            else 
                doHandle(target,baseRequest,request, response);
        }
    在執(zhí)行完doScope()方法后,調(diào)用nextScope()方法,該方法順著_nextScope鏈表走,直到盡頭,后調(diào)用doHandle()方法:
        public final void nextScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {
            if (_nextScope!=null)
                _nextScope.doScope(target,baseRequest,request, response);
            else if (_outerScope!=null)
                _outerScope.doHandle(target,baseRequest,request, response);
            else 
                doHandle(target,baseRequest,request, response);
        }
    而doHandle()方法在完成是調(diào)用nextHandle()方法,它也沿著_nextScope鏈表走,只要_nextScope和_handler相同,則調(diào)用其doHandle()方法,但是如果_nextScope和_handler不同,則調(diào)用_handler中的handle()方法,用于處理在ScopedHandler鏈表中插入非ScopedHandler的情況:
        public final void nextHandle(String target, final Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {
            if (_nextScope!=null && _nextScope==_handler)
                _nextScope.doHandle(target,baseRequest,request, response);
            else if (_handler!=null)
                _handler.handle(target,baseRequest, request, response);
        }

    使用

    在ScopedHandler的測試用例中給出了一個非常好的例子。首先有一個TestHandler繼承自ScopedHandler:
        private class TestHandler extends ScopedHandler {
            private final String _name;

            private TestHandler(String name) {
                _name=name;
            }

            @Override
            public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
                try {
                    _history.append(">S").append(_name);
                    super.nextScope(target,baseRequest,request, response);
                } finally {
                    _history.append("<S").append(_name);
                }
            }

            @Override
            public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
                try {
                    _history.append(">W").append(_name);
                    super.nextHandle(target,baseRequest,request,response);
                } finally {
                    _history.append("<W").append(_name);
                }
            }
        }
    然后有非ScopedHandler的實現(xiàn):
        private class OtherHandler extends HandlerWrapper {
            private final String _name;

            private OtherHandler(String name) {
                _name=name;
            }

            @Override
            public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
                try {
                    _history.append(">H").append(_name);
                    super.handle(target,baseRequest,request, response);
                } finally {
                    _history.append("<H").append(_name);
                }
            }
        }
    查看一下Test Case的執(zhí)行結(jié)果:
        @Test
        public void testDouble() throws Exception
        {
            TestHandler handler0 = new TestHandler("0");
            OtherHandler handlerA = new OtherHandler("A");
            TestHandler handler1 = new TestHandler("1");
            OtherHandler handlerB = new OtherHandler("B");
            handler0.setHandler(handlerA);
            handlerA.setHandler(handler1);
            handler1.setHandler(handlerB);
            handler0.start();
            handler0.handle("target",null,null,null);
            handler0.stop();
            String history=_history.toString();
            System.err.println(history);
            assertEquals(">S0>S1>W0>HA>W1>HB<HB<W1<HA<W0<S1<S0",history);
        }
    posted on 2014-05-07 23:49 DLevin 閱讀(1420) 評論(3)  編輯  收藏 所屬分類: Jetty

    FeedBack:
    # re: 深入Jetty源碼之ScopedHandler
    2014-05-08 08:25 | 金利鎖業(yè)
    支持博主分享啊  回復(fù)  更多評論
      
    # re: 深入Jetty源碼之ScopedHandler
    2014-05-08 08:52 | regale
    請問_history是怎么傳進(jìn)去的?  回復(fù)  更多評論
      
    # re: 深入Jetty源碼之ScopedHandler
    2014-05-08 09:17 | DLevin
    代碼沒有貼全,TestHandler和OtherHandler都是Test類中的內(nèi)部類,而_history是Test類的成員@regale
      回復(fù)  更多評論
      
    主站蜘蛛池模板: 日本免费网站在线观看| 三年片在线观看免费观看大全中国| 亚洲人成77777在线播放网站| 亚洲 无码 在线 专区| 又大又黄又粗又爽的免费视频 | 国产亚洲精品AAAA片APP| 亚洲欧美不卡高清在线| 亚洲爆乳精品无码一区二区| 亚洲第一成年免费网站| 羞羞视频免费网站含羞草| 特级毛片A级毛片100免费播放| 日日摸夜夜添夜夜免费视频| 巨胸喷奶水视频www免费视频| 中文在线免费看视频| 玖玖在线免费视频| 最近免费中文字幕mv电影| 先锋影音资源片午夜在线观看视频免费播放 | 好男人www免费高清视频在线| 成人性生免费视频| 国产精品酒店视频免费看 | 91久久青青草原线免费| 免费成人激情视频| 永久免费AV无码网站在线观看| 日韩亚洲国产综合久久久| 毛茸茸bbw亚洲人| 亚洲图片在线观看| 日本亚洲免费无线码| 美女视频黄视大全视频免费的| 国产在线观a免费观看| 99re6热视频精品免费观看| 最近最新MV在线观看免费高清| 日韩在线免费播放| 怡红院亚洲怡红院首页| 亚洲视频在线不卡| 亚洲av无码专区在线观看下载 | 亚洲高清一区二区三区| 一级中文字幕免费乱码专区| 麻豆精品成人免费国产片| 在线观看无码AV网站永久免费| 又黄又爽的视频免费看| 五月天网站亚洲小说|