一、前言
关于springframework的spring-web包中org.springframework.web.filter.CompositeFilter混合过滤器,通过将加入各种过滤器逻辑集filters加入到该混合器,按照过滤链FilterChain进行统一处理,详情参见源码说明部分。
二、源码说明
package org.springframework.web.filter;@b@@b@import java.io.IOException;@b@import java.util.ArrayList;@b@import java.util.List;@b@import javax.servlet.Filter;@b@import javax.servlet.FilterChain;@b@import javax.servlet.FilterConfig;@b@import javax.servlet.ServletException;@b@import javax.servlet.ServletRequest;@b@import javax.servlet.ServletResponse;@b@@b@public class CompositeFilter@b@ implements Filter@b@{@b@ private List<? extends Filter> filters;@b@@b@ public CompositeFilter()@b@ {@b@ this.filters = new ArrayList();@b@ }@b@@b@ public void setFilters(List<? extends Filter> filters) {@b@ this.filters = new ArrayList(filters);@b@ }@b@@b@ public void init(FilterConfig config)@b@ throws ServletException@b@ {@b@ for (Filter filter : this.filters)@b@ filter.init(config);@b@ }@b@@b@ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)@b@ throws IOException, ServletException@b@ {@b@ new VirtualFilterChain(chain, this.filters).doFilter(request, response);@b@ }@b@@b@ public void destroy()@b@ {@b@ for (int i = this.filters.size(); i-- > 0; ) {@b@ Filter filter = (Filter)this.filters.get(i);@b@ filter.destroy();@b@ }@b@ }@b@@b@ private static class VirtualFilterChain implements FilterChain {@b@ private final FilterChain originalChain;@b@ private final List<? extends Filter> additionalFilters;@b@ private int currentPosition = 0;@b@@b@ public VirtualFilterChain(FilterChain chain, List<? extends Filter> additionalFilters) {@b@ this.originalChain = chain;@b@ this.additionalFilters = additionalFilters;@b@ }@b@@b@ public void doFilter(ServletRequest request, ServletResponse response)@b@ throws IOException, ServletException@b@ {@b@ if (this.currentPosition == this.additionalFilters.size()) {@b@ this.originalChain.doFilter(request, response);@b@ }@b@ else {@b@ this.currentPosition += 1;@b@ Filter nextFilter = (Filter)this.additionalFilters.get(this.currentPosition - 1);@b@ nextFilter.doFilter(request, response, this);@b@ }@b@ }@b@ }@b@}