• 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     }
  • 相关阅读:
    Map接口框架图
    Collection接口框架图
    Java集合框架源码(四)——Vector
    Java集合框架源码(三)——arrayList
    HashSet与HashMap的区别
    Java集合框架源码(二)——hashSet
    hashMap与hashTable的区别
    HashMap与ConcurrentHashMap的区别
    asp.net 项目Net4.0 在IE10、 IE 11 下出现 “__doPostBack”未定义 的解决办法
    C# 完整List例子
  • 原文地址:https://www.cnblogs.com/yszzu/p/9626167.html
Copyright © 2020-2023  润新知