Filter责任链模式

 

 

Filter责任链的创建

org.apache.catalina.core.ApplicationFilterFactory#createFilterChain,  此方法是被org.apache.catalina.core.StandardWrapperValve#invoke调用的,  对每个request都会创建FilterChain

public static ApplicationFilterChain createFilterChain(ServletRequest request,
            Wrapper wrapper, Servlet servlet) {
//传入参数必须有一个servlet,这个servlet是在链的末尾被调用的. 这个servlet的查找过程是根据request的URI从web.xml配置中匹配出来的
        // If there is no servlet to execute, return null
        if (servlet == null)
            return null;

        // Create and initialize a filter chain object
        ApplicationFilterChain filterChain = null;
        if (request instanceof Request) {
            //.....
        } else {
            // Request dispatcher in use
            filterChain = new ApplicationFilterChain();
        }
// 责任链上绑定一个servlet
        filterChain.setServlet(servlet);
        filterChain.setServletSupportsAsync(wrapper.isAsyncSupported());

        // Acquire the filter mappings for this Context
        StandardContext context = (StandardContext) wrapper.getParent();
        FilterMap filterMaps[] = context.findFilterMaps();

        // If there are no filter mappings, we are done
        if ((filterMaps == null) || (filterMaps.length == 0))
            return (filterChain);

        // ...
//根据web.xml中filter的配置查找是否和当前request匹配
        // Add the relevant path-mapped filters to this filter chain
        for (int i = 0; i < filterMaps.length; i++) {
            if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
                continue;
            }
            if (!matchFiltersURL(filterMaps[i], requestPath))
                continue;
            ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
                context.findFilterConfig(filterMaps[i].getFilterName());
            if (filterConfig == null) {
                // FIXME - log configuration problem
                continue;
            }
// 和request URI匹配,则filter会加入到责任链中 filterChain.addFilter(filterConfig); }
/.....// Return the completed filter chain return filterChain; }

 

filterChain创建完成后就会调用doFilter启用这个链,  此方法也是被org.apache.catalina.core.StandardWrapperValve#invoke调用的

org.apache.catalina.core.ApplicationFilterChain#doFilter 

 1 private void internalDoFilter(ServletRequest request,
 2                                   ServletResponse response)
 3         throws IOException, ServletException {
 4 
 5         // Call the next filter if there is one  
 6         if (pos < n) {
 7             //调用下一个filter, 每调用一次 当前pos都会++
 8             ApplicationFilterConfig filterConfig = filters[pos++];
 9             try {
10                 Filter filter = filterConfig.getFilter();
11 
12                 //...
13                     filter.doFilter(request, response, this);
14                 
15             } catch (IOException | ServletException | RuntimeException e) {
16                 throw e;
17             } catch (Throwable e) {
18                // ...
19             }
20             return;
21         }
22 
23         // We fell off the end of the chain -- call the servlet instance
24         try {
25             if (request.isAsyncSupported() && !servletSupportsAsync) {
26                 request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR,
27                         Boolean.FALSE);
28             }
29             // ...  在链的末尾,调用具体servlet的doService
30                 servlet.service(request, response);
31             //
32         } catch (IOException | ServletException | RuntimeException e) {
33             throw e;
34         } catch (Throwable e) {
35            //...
36         } finally {
37            //...
38         }
39     }

 

posted @ 2018-09-11 10:38  funny_coding  阅读(1010)  评论(0编辑  收藏  举报
build beautiful things, share happiness