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