《JAVA与模式》之责任链模式(四)

2014-11-24 02:08:38 · 作者: · 浏览: 2
类的invoke()方法中被调用的。

  \

  由于invoke()方法较长,所以将很多地方省略。

复制代码
    public final void invoke(Request request, Response response)
        throws IOException, ServletException {
   ...省略中间代码
     // Create the filter chain for this request
        ApplicationFilterFactory factory =
            ApplicationFilterFactory.getInstance();
        ApplicationFilterChain filterChain =
            factory.createFilterChain(request, wrapper, servlet);
  ...省略中间代码
         filterChain.doFilter(request.getRequest(), response.getResponse());
  ...省略中间代码
    }
复制代码

  那正常的流程应该是这样的:

  在StandardWrapperValue类的invoke()方法中调用ApplicationFilterChai类的createFilterChain()方法―――>在ApplicationFilterChai类的createFilterChain()方法中调用ApplicationFilterChain类的addFilter()方法―――>在ApplicationFilterChain类的addFilter()方法中给ApplicationFilterConfig数组赋值。

\

  根据上面的代码可以看出StandardWrapperValue类的invoke()方法在执行完createFilterChain()方法后,会继续执行ApplicationFilterChain类的doFilter()方法,然后在doFilter()方法中会调用internalDoFilter()方法。

  以下是internalDoFilter()方法的部分代码

复制代码
        // Call the next filter if there is one
        if (pos < n) {
       //拿到下一个Filter,将指针向下移动一位
            //pos它来标识当前ApplicationFilterChain(当前过滤器链)执行到哪个过滤器
            ApplicationFilterConfig filterConfig = filters[pos++];
            Filter filter = null;
            try {
          //获取当前指向的Filter的实例
                filter = filterConfig.getFilter();
                support.fireInstanceEvent(InstanceEvent.BEFORE_FILTER_EVENT,
                                          filter, request, response);
                
                if (request.isAsyncSupported() && "false".equalsIgnoreCase(
                        filterConfig.getFilterDef().getAsyncSupported())) {
                    request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR,
                            Boolean.FALSE);
                }
                if( Globals.IS_SECURITY_ENABLED ) {
                    final ServletRequest req = request;
                    final ServletResponse res = response;
                    Principal principal = 
                        ((HttpServletRequest) req).getUserPrincipal();

                    Object[] args = new Object[]{req, res, this};
                    SecurityUtil.doAsPrivilege
                        ("doFilter", filter, classType, args, principal);
                    
                } else {
            //调用Filter的doFilter()方法  
                    filter.doFilter(request, response, this);
                }
复制代码

  这里的filter.doFilter(request, response, this);就是调用我们前面创建的TestFilter中的doFilter()方法。而TestFilter中的doFilter()方法会继续调用chain.doFilter(request, response);方法,而这个chain其实就是ApplicationFilterChain,所以调用过程又回到了上面调用dofilter和调用internalDoFilter方法,这样执行直到里面的过滤器全部执行。

  如果定义两个过滤器,则Debug结果如下:

\