责任链

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...
未来舞台很大,要自信,自己其实是可以做很多东西的...

你可能感兴趣的:(责任链)