责任链

作者: 追梦小蜗牛 | 来源:发表于2020-12-08 15:57 被阅读0次
    pexels-stephane-navailles-3415410.jpg

    介绍:

    责任链模式为请求创建一个接收者对象链,每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把请求传给下一个接收者。

    UML:

    UML.png

    角色:

    • Handler : 抽象类,定义一个抽象方法:handleRequest,子类实现。
    • ConcreteHandler:具体请求的处理者,如果满足当前Handler的限制条件,则处理,继续向下传递。
    • Client:设置不同实现类的层级,也就是处理的顺序。

    应用场景:

    • Zuul中的filter
    • Tomcat中的filter
    • Tomcat中的部分容器组件

    demo简单叙述:

    关键类:
    final类:ApplicationFilterChain、接口:FilterChain、管理filter的类:ApplicationFilterConfig


    image.png

    关键方法:
    FilterChain的doFilter方法、ApplicationFilterChain的internalDoFilter方法。
    设置不同filter执行的顺序方法:
    采用一个ApplicationFilterConfig类型的数组(数组是有序的),ApplicationFilterConfig里面会有一个Fillter的引用。
    关键代码:

    private void internalDoFilter(ServletRequest request,
                                      ServletResponse response)
            throws IOException, ServletException {
    
            // Call the next filter if there is one
            if (pos < n) {
                ApplicationFilterConfig filterConfig = filters[pos++];
                try {
                    Filter filter = filterConfig.getFilter();//@1
                    filter.doFilter(request, response, this);//@2
                } catch (IOException | ServletException | RuntimeException e) {
                    throw e;
                } catch (Throwable e) {
                    e = ExceptionUtils.unwrapInvocationTargetException(e);
                    ExceptionUtils.handleThrowable(e);
                    throw new ServletException(sm.getString("filterChain.filter"), e);
                }
                return;
            }
    
            // We fell off the end of the chain -- call the servlet instance
            try {
                    servlet.service(request, response);//@3
                }
            } catch (IOException | ServletException | RuntimeException e) {
                throw e;
            } catch (Throwable e) {
                e = ExceptionUtils.unwrapInvocationTargetException(e);
                ExceptionUtils.handleThrowable(e);
                throw new ServletException(sm.getString("filterChain.servlet"), e);
            } finally {
                if (ApplicationDispatcher.WRAP_SAME_OBJECT) {
                    lastServicedRequest.set(null);
                    lastServicedResponse.set(null);
                }
            }
        }
    

    @1、@2、@3:@3代表filter执行完之后,最终会执行servlet的service方法,还是会回归到业务层面,filter仅仅是用来扩展和补充一些额外的逻辑,还有listener的功能也和filter类似...

    总结:

    责任链模式相对来说不是那么的复杂,一般是一组对象都可能会处理当前的请求,关键就是看请求是否符合对象的限制条件,符合就处理,不符合,就跳过。
    这些对象一般都是按照一定顺序处理的,一层一层的调用下去...设置这些对象的顺序的方法可以很灵活,最基础的就是先new 出来所有参与的对象,然后通过setHandler的方式去设置这种引用关系。
    像Tomcat中ApplicationFilterChain很明显就是借用数组这种数据结构的特性来设置。
    Zuul中的filter用的好像是用一个返回int类型的方法来设置的。
    思考问题方法:
    WHAT--->HOW--->WHY...
    未来舞台很大,要自信,自己其实是可以做很多东西的...

    相关文章

      网友评论

          本文标题:责任链

          本文链接:https://www.haomeiwen.com/subject/tbofgktx.html