?
?
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 nullif (servlet == null)return null;// Create and initialize a filter chain objectApplicationFilterChain filterChain = null;if (request instanceof Request) {//.....} else {// Request dispatcher in usefilterChain = new ApplicationFilterChain();} // 責任鏈上綁定一個servletfilterChain.setServlet(servlet);filterChain.setServletSupportsAsync(wrapper.isAsyncSupported());// Acquire the filter mappings for this ContextStandardContext context = (StandardContext) wrapper.getParent();FilterMap filterMaps[] = context.findFilterMaps();// If there are no filter mappings, we are doneif ((filterMaps == null) || (filterMaps.length == 0))return (filterChain);// ... //根據web.xml中filter的配置查找是否和當前request匹配// Add the relevant path-mapped filters to this filter chainfor (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 problemcontinue;}
// 和request URI匹配,則filter會加入到責任鏈中filterChain.addFilter(filterConfig);}/.....// Return the completed filter chainreturn 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 }
?