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

2014-11-24 02:08:38 · 作者: · 浏览: 3
nfig数组长度为零,那它是在什么时候被重新赋值的呢?

    private ApplicationFilterConfig[] filters = 
        new ApplicationFilterConfig[0];

  是在调用ApplicationFilterChain类的addFilter()方法时。

    /**
     * The int which gives the current number of filters in the chain.
     */
    private int n = 0;
    public static final int INCREMENT = 10;
复制代码
    void addFilter(ApplicationFilterConfig filterConfig) {

        // Prevent the same filter being added multiple times
        for(ApplicationFilterConfig filter:filters)
            if(filter==filterConfig)
                return;

        if (n == filters.length) {
            ApplicationFilterConfig[] newFilters =
                new ApplicationFilterConfig[n + INCREMENT];
            System.arraycopy(filters, 0, newFilters, 0, n);
            filters = newFilters;
        }
        filters[n++] = filterConfig;

    }
复制代码

  变量n用来记录当前过滤器链里面拥有的过滤器数目,默认情况下n等于0,ApplicationFilterConfig对象数组的长度也等于0,所以当第一次调用addFilter()方法时,if (n == filters.length)的条件成立,ApplicationFilterConfig数组长度被改变。之后filters[n++] = filterConfig;将变量filterConfig放入ApplicationFilterConfig数组中并将当前过滤器链里面拥有的过滤器数目+1。

  那ApplicationFilterChain的addFilter()方法又是在什么地方被调用的呢?

  是在ApplicationFilterFactory类的createFilterChain()方法中。

复制代码
  1     public ApplicationFilterChain createFilterChain
  2         (ServletRequest request, Wrapper wrapper, Servlet servlet) {
  3 
  4         // get the dispatcher type
  5         DispatcherType dispatcher = null; 
  6         if (request.getAttribute(DISPATCHER_TYPE_ATTR) != null) {
  7             dispatcher = (DispatcherType) request.getAttribute(DISPATCHER_TYPE_ATTR);
  8         }
  9         String requestPath = null;
 10         Object attribute = request.getAttribute(DISPATCHER_REQUEST_PATH_ATTR);
 11         
 12         if (attribute != null){
 13             requestPath = attribute.toString();
 14         }
 15         
 16         // If there is no servlet to execute, return null
 17         if (servlet == null)
 18             return (null);
 19 
 20         boolean comet = false;
 21         
 22         // Create and initialize a filter chain object
 23         ApplicationFilterChain filterChain = null;
 24         if (request instanceof Request) {
 25             Request req = (Request) request;
 26             comet = req.isComet();
 27             if (Globals.IS_SECURITY_ENABLED) {
 28                 // Security: Do not recycle
 29                 filterChain = new ApplicationFilterChain();
 30                 if (comet) {
 31                     req.setFilterChain(filterChain);
 32                 }
 33             } else {
 34                 filterChain = (ApplicationFilterChain) req.getFilterChain();
 35                 if (filterChain == null) {
 36                     filterChain = new ApplicationFilterChain();
 37                     req.setFilterChain(filterChain);
 38                 }
 39             }
 40         } else {
 41             // Request dispatcher in use
 42             filterChain = new ApplicationFilterChain();
 43         }
 44 
 45         filterChain.setServlet(servlet);
 46 
 47         filterChain.setSupport
 48             (((StandardWrapper)wrapper).getInstanceSupport());
 49 
 50         // Acquire the filter mappings for this Context
 51         StandardContext context = (StandardContext) wrapper.getParent();
 52         FilterMap filterMaps[] = context.findFilterMaps();
 53 
 54         // If there are no filter mappings, we are done
 55         if ((filterMaps == null) || (filterMaps.length == 0))
 56             return (filterChain);
 57 
 58         // Acquire the information we will need to match filter mappings
 59         String servletName = wrapper.getName();
 60 
 61         // Add the relevant path-mapped filters to this filter chain
 62         for (int i = 0; i < filterMaps.length; i++) {
 63             if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
 64                 continue;
 65             }
 66             if (!matchFiltersURL(filterMaps[i], requestPath))
 67                 continue;
 68             ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
 69                 context.findFilterConfig(filterMaps[i].getFilterName());
 70             if (filterConfig == null) {
 71                 // FIXME - log configuration problem
 72                 continue;
 73             }
 74             boolean isCometFilter = false;
 75             if (comet) {
 76                 try {
 77                     isCometFilter = filterConfig.getFilter() instanceof CometFilter;
 78                 } catch (Exception e) {
 79                     // Note: The try catch is there because getFilter has a lot of 
 80                     // declared exceptions. However, the filter is allocated much
 81                     // earlier
 82                     Throwable t = ExceptionUtils.unwrapInvocationTargetException(e);
 83                     ExceptionUtils.handleThrowable(t);
 84                 }
 85                 if (isCometFilter) {
 86                     filterChain.addFilter(filterConfig);
 87                 }
 88             } else {
 89                 filterChain.addFilter(filterConfig);
 90             }
 91         }
 92 
 93         // Add filters that match on servlet name second
 94         for (int i = 0; i < filterMaps.length; i++) {
 95             if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
 96                 continue;
 97             }
 98             if (!matchFiltersServlet(filterMaps[i], servletName))
 99                 continue;
100             ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
101                 context.findFilterConfig(filterMaps[i].getFilterName());
102             if (filterConfig == null) {
103                 // FIXME - log configuration problem
104                 continue;
105             }
106             boolean isCometFilter = false;
107             if (comet) {
108                 try {
109                     isCometFilter = filterConfig.getFilter() instanceof CometFilter;
110                 } catch (Exception e) {
111                     // Note: The try catch is there because getFilter has a lot of 
112                     // declared exceptions. However, the filter is allocated much
113                     // earlier
114                 }
115                 if (isCometFilter) {
116                     filterChain.addFilter(filterConfig);
117                 }
118             } else {
119                 filterChain.addFilter(filterConfig);
120             }
121         }
122 
123         // Return the completed filter chain
124         return (filterChain);
125 
126     }
复制代码

  可以将如上代码分为两段,51行之前为第一段,51行之后为第二段。

  第一段的主要目的是创建ApplicationFilterChain对象以及一些参数设置。

  第二段的主要目的是从上下文中获取所有Filter信息,之后使用for循环遍历并调用filterChain.addFilter(filterConfig);将filterConfig放入ApplicationFilterChain对象的ApplicationFilterConfig数组中。

  那ApplicationFilterFactory类的createFilterChain()方法又是在什么地方被调用的呢?

  是在StandardWrapperValue