Tomcat Filter流程

Spring Filter

使用

实现filter接口

public class A implements java.servletx.Filter{
    private FilterConfig filterConfig = null;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        paramValue = filterConfig.getInitParameter("encoding");
    }
	@Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
		System.out.println("过滤器A");
        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override
    public void destroy() {
        this.filterConfig = null;
    }
}

spring注册

<filter>
    <filter-name>A</filter-name>
    <filter-class>A</filter-class>
    <init-param>
    <param-name>encoding</param-name>
    <param-value>GB2312</param-value>
    </init-param>
</filter>

springboot注册

//继承FilterRegistrationBean  springboot 会自动扫描所有的FilterRegistrationBean 将返回的filter注册到容器中
public class AuthFilterRegistrationBean extends FilterRegistrationBean<Filter> {
    @Autowired
    UserService userService;

    @Override
    public Filter getFilter() {
        return new AuthFilter();
    }

    class AuthFilter implements Filter {
        ...
    }
}

源码解读

请求过滤需要的Filter接口

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    default void destroy() {
    }
}
public interface FilterChain {
    void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}
public interface FilterConfig {
    String getFilterName();

    ServletContext getServletContext();

    String getInitParameter(String var1);

    Enumeration<String> getInitParameterNames();
}

需要注意:

如果过滤器中没有调用chain.doFilter 那么

1. 后面的拦截器都不会执行
2. servlet.service 也不执行  开始弹出栈帧  相当于拦截器
//FilterChain实现
public final class ApplicationFilterChain implements FilterChain {
	//filter完成后 执行 service 方法
    //生命周期是servlet的生命周期
	private Servlet servlet = null;
	//定义多个filterConfig 通过filterConfig 获取filter
	private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
	//用来判断是否责任链是否结束 当前位置
	private int pos = 0;
	//过滤链总的大小
    private int n = 0;
    
    //添加一个过滤器
    void addFilter(ApplicationFilterConfig filterConfig) {
        ApplicationFilterConfig[] newFilters = this.filters;
        int var3 = newFilters.length;

		//先判断是否已存在
        for(int var4 = 0; var4 < var3; ++var4) {
            ApplicationFilterConfig filter = newFilters[var4];
            if (filter == filterConfig) {
                return;
            }
        }
		//数组扩容
        if (this.n == this.filters.length) {
            newFilters = new ApplicationFilterConfig[this.n + 10];
            System.arraycopy(this.filters, 0, newFilters, 0, this.n);
            this.filters = newFilters;
        }
		//把filter加进去 2个操作
		//容量加1
		//数组内容加1
        this.filters[this.n++] = filterConfig;
    }
    
    //链式调用的方法 这个方法只是判断是否开启安全管理
    //具体的处理在internalDoFilter这个方法
    public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
        if (Globals.IS_SECURITY_ENABLED) {
            ServletRequest req = request;
            ServletResponse res = response;

            try {
                AccessController.doPrivileged(() -> {
                    this.internalDoFilter(req, res);
                    return null;
                });
            } catch (PrivilegedActionException var7) {
                Exception e = var7.getException();
                if (e instanceof ServletException) {
                    throw (ServletException)e;
                }

                if (e instanceof IOException) {
                    throw (IOException)e;
                }

                if (e instanceof RuntimeException) {
                    throw (RuntimeException)e;
                }

                throw new ServletException(e.getMessage(), e);
            }
        } else {
            this.internalDoFilter(request, response);
        }

    }
    
    //具体的过滤处理
    private void internalDoFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
        //判断是否已经到过滤器链的结束
        //如果过滤器中没有chain.doFilter 那么就会开始退栈  导致service方法不执行
        if (this.pos < this.n) {
        	//pos加1
        	//获取下一个过滤器
            ApplicationFilterConfig filterConfig = this.filters[this.pos++];

            try {
                Filter filter = filterConfig.getFilter();
                if (request.isAsyncSupported() && "false".equalsIgnoreCase(filterConfig.getFilterDef().getAsyncSupported())) {
                    request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", Boolean.FALSE);
                }

				//调用过滤器的方法
                if (Globals.IS_SECURITY_ENABLED) {
                    Principal principal = ((HttpServletRequest)request).getUserPrincipal();
                    Object[] args = new Object[]{request, response, this};
                    SecurityUtil.doAsPrivilege("doFilter", filter, classType, args, principal);
                } else {
                    filter.doFilter(request, response, this);
                }

            } catch (ServletException | RuntimeException | IOException var15) {
                throw var15;
            } catch (Throwable var16) {
                Throwable e = ExceptionUtils.unwrapInvocationTargetException(var16);
                ExceptionUtils.handleThrowable(e);
                throw new ServletException(sm.getString("filterChain.filter"), e);
            }
        } else {
            try {
                if (ApplicationDispatcher.WRAP_SAME_OBJECT) {
                    lastServicedRequest.set(request);
                    lastServicedResponse.set(response);
                }

                if (request.isAsyncSupported() && !this.servletSupportsAsync) {
                    request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", Boolean.FALSE);
                }
				
				//最后一个过滤器用进入servlet 的 service 方法
				//没调用一次doFilter 栈帧都会增长
				//这里需要注意,没有return 所以过滤器链 和 所有过滤器 的栈帧不会退出,会等待servlet.service执行完毕
                if (request instanceof HttpServletRequest && response instanceof HttpServletResponse && Globals.IS_SECURITY_ENABLED) {
                    Principal principal = ((HttpServletRequest)request).getUserPrincipal();
                    Object[] args = new Object[]{request, response};
                    SecurityUtil.doAsPrivilege("service", this.servlet, classTypeUsedInService, args, principal);
                } else {
                    this.servlet.service(request, response);
                }
            } catch (ServletException | RuntimeException | IOException var17) {
                throw var17;
            } catch (Throwable var18) {
                Throwable e = ExceptionUtils.unwrapInvocationTargetException(var18);
                ExceptionUtils.handleThrowable(e);
                throw new ServletException(sm.getString("filterChain.servlet"), e);
            } finally {
                if (ApplicationDispatcher.WRAP_SAME_OBJECT) {
                    lastServicedRequest.set((Object)null);
                    lastServicedResponse.set((Object)null);
                }

            }

        }
    }
    
}

应用启动需要的接口

  • ApplicationFilterConfig
  • FilterDef
  • FilterMap
//filterchain中添加的是这个类
//这个类是依赖FilterDef生成的
//Filter类的初始化又依赖这个类
public final class ApplicationFilterConfig implements FilterConfig, Serializable {
	//应用上下文
	private final transient Context context;
    //过滤器
    private transient Filter filter = null;
    //过滤器定义
    private final FilterDef filterDef;
    
    //初始化filter
    private void initFilter() throws ServletException {
        if (this.context instanceof StandardContext && this.context.getSwallowOutput()) {
            boolean var5 = false;

            try {
                var5 = true;
                SystemLogHandler.startCapture();
                //根据filterconfig初始化filter
                this.filter.init(this);
                var5 = false;
            } finally {
                if (var5) {
                    String capturedlog = SystemLogHandler.stopCapture();
                    if (capturedlog != null && capturedlog.length() > 0) {
                        this.getServletContext().log(capturedlog);
                    }

                }
            }

            String capturedlog = SystemLogHandler.stopCapture();
            if (capturedlog != null && capturedlog.length() > 0) {
                this.getServletContext().log(capturedlog);
            }
        } else {
            this.filter.init(this);
        }

		//注册到java jmx管理中心
        this.registerJMX();
    }
}
public class FilterDef implements Serializable {
	//filter对象实例
	private transient Filter filter = null;
    //类名 反射会用到
    private String filterClass = null;
    //filter对应的别名
    private String filterName = null;
    //参数 用于filter的初始化init
    private final Map<String, String> parameters = new HashMap();
}
public class FilterMap extends XmlEncodingBase implements Serializable {
	private String filterName = null;
    private String[] servletNames = new String[0];
}

启动前的加载过程

  • ServletContext
  • ApplicationContext
  • StandardContext

servlet上下文 接口中声明 添加filter接口 用来将filter添加到应用上下文

生成webserver需要用到这个实例

public interface ServletContext {
	//通过类名加载
	javax.servlet.FilterRegistration.Dynamic addFilter(String var1, String var2);
	//直接加载实例
    javax.servlet.FilterRegistration.Dynamic addFilter(String var1, Filter var2);
	//通过类型加载
    javax.servlet.FilterRegistration.Dynamic addFilter(String var1, Class<? extends Filter> var2);
}

ApplicationContext

实现了 ServletContext 中的 addFilter 方法

向属性中的StandandContext实例添加filterDef

public class ApplicationContext implements ServletContext {
    //标准上下文属性  包含 filterConfigs filterMaps filterDefs 属性
	private final StandardContext context;
    
    //调用StandandContext添加filterDef
    private FilterRegistration.Dynamic addFilter(String filterName,
            String filterClass, Filter filter) throws IllegalStateException {

        if (filterName == null || filterName.equals("")) {
            throw new IllegalArgumentException(sm.getString(
                    "applicationContext.invalidFilterName", filterName));
        }

        if (!context.getState().equals(LifecycleState.STARTING_PREP)) {
            //TODO Spec breaking enhancement to ignore this restriction
            throw new IllegalStateException(
                    sm.getString("applicationContext.addFilter.ise",
                            getContextPath()));
        }

        FilterDef filterDef = context.findFilterDef(filterName);

        // Assume a 'complete' FilterRegistration is one that has a class and
        // a name
        if (filterDef == null) {
            filterDef = new FilterDef();
            filterDef.setFilterName(filterName);
            context.addFilterDef(filterDef);
        } else {
            if (filterDef.getFilterName() != null &&
                    filterDef.getFilterClass() != null) {
                return null;
            }
        }

        if (filter == null) {
            filterDef.setFilterClass(filterClass);
        } else {
            filterDef.setFilterClass(filter.getClass().getName());
            filterDef.setFilter(filter);
        }

        return new ApplicationFilterRegistration(filterDef, context);
    }
    
}

StandandContext类

filter关键的3个属性和2个方法

  • filterMaps

  • filterDefs

  • filterConfigs

  • addFilterDef(填充filterDef对象)

  • filterStart(初始化 filterConfigs )

在ApplicationContext中调用addFilterDef方法

//tomcat 标准 context
public class StandardContext extends ContainerBase
        implements Context, NotificationEmitter {
        
	//servletContext 
    protected ApplicationContext context = null;
    //获取servletContext
    @Override
    public ServletContext getServletContext() {
        if (context == null) {
            context = new ApplicationContext(this);
            if (altDDName != null)
                context.setAttribute(Globals.ALT_DD_ATTR,altDDName);
        }
        return context.getFacade();
    }
        
    //filterMaps 封装的对象
    private final ContextFilterMaps filterMaps = new ContextFilterMaps();    
    @Override
    //servletContext添加filter时调用
    public void addFilterMap(FilterMap filterMap) {
        validateFilterMap(filterMap);
        // Add this filter mapping to our registered set
        filterMaps.add(filterMap);
        fireContainerEvent("addFilterMap", filterMap);
    }
    //获取filterMaps 
    //请求到达时获取
    @Override
    public FilterMap[] findFilterMaps() {
        return filterMaps.asArray();
    }
    
    //filtername 和 filterconfig 映射
    private Map<String, ApplicationFilterConfig> filterConfigs = new HashMap<>();
    //通过filtername获取filterconfig bean实例
    public FilterConfig findFilterConfig(String name) {
        return filterConfigs.get(name);
    }
    //通过 filterDefs 生成 filterconfigs 映射
    /**
     * Configure and initialize the set of filters for this Context.
     * @return <code>true</code> if all filter initialization completed
     * successfully, or <code>false</code> otherwise.
     */
    public boolean filterStart() {

        if (getLogger().isDebugEnabled()) {
            getLogger().debug("Starting filters");
        }
        // Instantiate and record a FilterConfig for each defined filter
        boolean ok = true;
        synchronized (filterConfigs) {
            filterConfigs.clear();
            for (Entry<String,FilterDef> entry : filterDefs.entrySet()) {
                String name = entry.getKey();
                if (getLogger().isDebugEnabled()) {
                    getLogger().debug(" Starting filter '" + name + "'");
                }
                try {
                    ApplicationFilterConfig filterConfig =
                            new ApplicationFilterConfig(this, entry.getValue());
                    filterConfigs.put(name, filterConfig);
                } catch (Throwable t) {
                    t = ExceptionUtils.unwrapInvocationTargetException(t);
                    ExceptionUtils.handleThrowable(t);
                    getLogger().error(sm.getString(
                            "standardContext.filterStart", name), t);
                    ok = false;
                }
            }
        }

        return ok;
    }
    
    
    //filterDefs定义
    private Map<String, FilterDef> filterDefs = new HashMap<>();
    //添加filterDef
    public void addFilterDef(FilterDef filterDef) {

        synchronized (filterDefs) {
            filterDefs.put(filterDef.getFilterName(), filterDef);
        }
        fireContainerEvent("addFilterDef", filterDef);

    }
    //查找filterDef
    public FilterDef findFilterDef(String filterName) {
        synchronized (filterDefs) {
            return filterDefs.get(filterName);
        }
    }
    
}

ServletContextInitializer

对ServletContext对象进行初始化操作

//servlet上下文初始化接口
public interface ServletContextInitializer {
    //给servletContext填充属性  进行初始化
    //异步操作 先实例 再初始化
    void onStartup(ServletContext servletContext) throws ServletException;
}

ServletContextInitializer的实现

public abstract class AbstractFilterRegistrationBean<T extends Filter> extends DynamicRegistrationBean<Dynamic> {
	public final void onStartup(ServletContext servletContext) throws ServletException {
        String description = this.getDescription();
        if (!this.isEnabled()) {
            logger.info(StringUtils.capitalize(description) + " was not registered (disabled)");
        } else {
        	//注册
            this.register(description, servletContext);
        }
    }
    
    protected final void register(String description, ServletContext servletContext) {
        D registration = this.addRegistration(description, servletContext);
        if (registration == null) {
            logger.info(StringUtils.capitalize(description) + " was not registered (possibly already registered?)");
        } else {
            //配置registration
            this.configure(registration);
        }
    }
    
    protected Dynamic addRegistration(String description, ServletContext servletContext) {
        Filter filter = this.getFilter();
        //servletContext 添加 filter
        return servletContext.addFilter(this.getOrDeduceName(filter), filter);
    }
    
}	

通过配置将AbstractFilterRegistrationBean加载到容器中

并且配置到servlet的ServletContextInitializerBeans中

等待被webserver(tomcat)调用

//封装多个servletContenctInitializer上下文初始化接口实例
//通过beanFactory ioc 容器来生成上下文实例
public class ServletContextInitializerBeans extends AbstractCollection<ServletContextInitializer> {
	 //一个类型和初始化接口的映射
	 private final MultiValueMap<Class<?>, ServletContextInitializer> initializers = new LinkedMultiValueMap();
	 
	 public ServletContextInitializerBeans(ListableBeanFactory beanFactory, Class<? extends ServletContextInitializer>... initializerTypes) {
	 	
	 }
}

TomcatStarter

​ 调用 ServletContextInitializer.onStartup(ServletContext) 来初始化 ServletContext

class TomcatStarter implements ServletContainerInitializer {
    private static final Log logger = LogFactory.getLog(TomcatStarter.class);
    private final ServletContextInitializer[] initializers;
    private volatile Exception startUpException;

    TomcatStarter(ServletContextInitializer[] initializers) {
        this.initializers = initializers;
    }

    public void onStartup(Set<Class<?>> classes, ServletContext servletContext) throws ServletException {
        try {
            ServletContextInitializer[] var3 = this.initializers;
            int var4 = var3.length;

            for(int var5 = 0; var5 < var4; ++var5) {
                ServletContextInitializer initializer = var3[var5];
                //被调用
                initializer.onStartup(servletContext);
            }
        } catch (Exception var7) {
            this.startUpException = var7;
            if (logger.isErrorEnabled()) {
                logger.error("Error starting Tomcat context. Exception: " + var7.getClass().getName() + ". Message: " + var7.getMessage());
            }
        }

    }

    Exception getStartUpException() {
        return this.startUpException;
    }
}

servletContext实例

public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext {
	private ServletContextInitializer getSelfInitializer() {
        return this::selfInitialize;
    }
	
	//初始化 onStartup 执行的方法
    private void selfInitialize(ServletContext servletContext) throws ServletException {
        this.prepareWebApplicationContext(servletContext);
        this.registerApplicationScope(servletContext);
        WebApplicationContextUtils.registerEnvironmentBeans(this.getBeanFactory(), servletContext);
        Iterator var2 = this.getServletContextInitializerBeans().iterator();

        while(var2.hasNext()) {
            ServletContextInitializer beans = (ServletContextInitializer)var2.next();
            beans.onStartup(servletContext);
        }

    }
    
    //通过本类的实例构造一个webServer(Tomcat)
    //并且初始化
    private void createWebServer() {
        WebServer webServer = this.webServer;
        ServletContext servletContext = this.getServletContext();
        if (webServer == null && servletContext == null) {
            StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");
            ServletWebServerFactory factory = this.getWebServerFactory();
            createWebServer.tag("factory", factory.getClass().toString());
            this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});
            createWebServer.end();
            this.getBeanFactory().registerSingleton("webServerGracefulShutdown", new WebServerGracefulShutdownLifecycle(this.webServer));
            this.getBeanFactory().registerSingleton("webServerStartStop", new WebServerStartStopLifecycle(this, this.webServer));
        } else if (servletContext != null) {
            try {
                this.getSelfInitializer().onStartup(servletContext);
            } catch (ServletException var5) {
                throw new ApplicationContextException("Cannot initialize servlet context", var5);
            }
        }

        this.initPropertySources();
    }
    
    //添加过滤器
    private Dynamic addFilter(String filterName, String filterClass, Filter filter) throws IllegalStateException {
        if (filterName != null && !filterName.equals("")) {
            if (!this.context.getState().equals(LifecycleState.STARTING_PREP)) {
                throw new IllegalStateException(sm.getString("applicationContext.addFilter.ise", new Object[]{this.getContextPath()}));
            } else {
                FilterDef filterDef = this.context.findFilterDef(filterName);
                if (filterDef == null) {
                    filterDef = new FilterDef();
                    filterDef.setFilterName(filterName);
                    this.context.addFilterDef(filterDef);
                } else if (filterDef.getFilterName() != null && filterDef.getFilterClass() != null) {
                    return null;
                }

                if (filter == null) {
                    filterDef.setFilterClass(filterClass);
                } else {
                    filterDef.setFilterClass(filter.getClass().getName());
                    filterDef.setFilter(filter);
                }

                return new ApplicationFilterRegistration(filterDef, this.context);
            }
        } else {
            throw new IllegalArgumentException(sm.getString("applicationContext.invalidFilterName", new Object[]{filterName}));
        }
    }
    
}

请求到达时的处理流程

从StandandContext中获取filterMap

从filterMap中找到和request对象能匹配到的filter-name

从StandandContext中通过filter-name找到filter-config实例

https://blog.csdn.net/wq5350/article/details/108719708

final class StandardWrapperValve extends ValveBase {
	public final void invoke(Request request, Response response)
        throws IOException, ServletException {

        //省略其他不做分析

        //重点在这 创建filterchain
        //每个请求都会创建一个filterchain 
        //并不是所有的请求共用一个
        // Create the filter chain for this request
        ApplicationFilterChain filterChain =
                ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);

        // Call the filter chain for this request
        // NOTE: This also calls the servlet's service() method
        Container container = this.container;
        try {
            if ((servlet != null) && (filterChain != null)) {
                // Swallow output if needed
                if (context.getSwallowOutput()) {
                    try {
                        SystemLogHandler.startCapture();
                        if (request.isAsyncDispatching()) {
                            request.getAsyncContextInternal().doInternalDispatch();
                        } else {
                            filterChain.doFilter(request.getRequest(),
                                    response.getResponse());
                        }
                    } finally {
                        String log = SystemLogHandler.stopCapture();
                        if (log != null && log.length() > 0) {
                            context.getLogger().info(log);
                        }
                    }
                } else {
                    if (request.isAsyncDispatching()) {
                        request.getAsyncContextInternal().doInternalDispatch();
                    } else {
                        filterChain.doFilter
                            (request.getRequest(), response.getResponse());
                    }
                }

            }
        } catch (ClientAbortException | CloseNowException e) {
        	
            //省略异常处理
            
        } finally {
            
            //请求处理完成后 要释放掉filterchain
            //使得filter可以被垃圾处理器回收
            
            // Release the filter chain (if any) for this request
            if (filterChain != null) {
                filterChain.release();
            }

            //省略后续操作
            
        }
    }
        
}
public final class ApplicationFilterFactory {

	//创建filterchain
	public static ApplicationFilterChain createFilterChain(ServletRequest request,
            Wrapper wrapper, Servlet servlet) {

        // If there is no servlet to execute, return null
        if (servlet == null)
            return null;

		//实例化一个filterchain
        // Create and initialize a filter chain object
        ApplicationFilterChain filterChain = null;
        if (request instanceof Request) {
            Request req = (Request) request;
            if (Globals.IS_SECURITY_ENABLED) {
                // Security: Do not recycle
                filterChain = new ApplicationFilterChain();
            } else {
            	//复用filterchain
                filterChain = (ApplicationFilterChain) req.getFilterChain();
                if (filterChain == null) {
                    filterChain = new ApplicationFilterChain();
                    req.setFilterChain(filterChain);
                }
            }
        } else {
            // Request dispatcher in use
            filterChain = new ApplicationFilterChain();
        }

		//初始化配置
        filterChain.setServlet(servlet);
        filterChain.setServletSupportsAsync(wrapper.isAsyncSupported());

		//从context中获取filterMap
        // 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;

        // Acquire the information we will need to match filter mappings
        DispatcherType dispatcher =
                (DispatcherType) request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);

        String requestPath = null;
        Object attribute = request.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR);
        if (attribute != null){
            requestPath = attribute.toString();
        }

        String servletName = wrapper.getName();

		//从filterMap中寻找匹配路径的filter添加到链中
        // Add the relevant path-mapped filters to this filter chain
        for (FilterMap filterMap : filterMaps) {
            if (!matchDispatcher(filterMap, dispatcher)) {
                continue;
            }
            if (!matchFiltersURL(filterMap, requestPath))
                continue;
            ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
                    context.findFilterConfig(filterMap.getFilterName());
            if (filterConfig == null) {
                // FIXME - log configuration problem
                continue;
            }
            filterChain.addFilter(filterConfig);
        }

		//如果匹配到servlet名 也添加进去
        // Add filters that match on servlet name second
        for (FilterMap filterMap : filterMaps) {
            if (!matchDispatcher(filterMap, dispatcher)) {
                continue;
            }
            if (!matchFiltersServlet(filterMap, servletName))
                continue;
            ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
                    context.findFilterConfig(filterMap.getFilterName());
            if (filterConfig == null) {
                // FIXME - log configuration problem
                continue;
            }
            filterChain.addFilter(filterConfig);
        }

        // Return the completed filter chain
        return filterChain;
    }
}

责任链模式

类似于递归压栈

总结

流程

  1. context启动时,调用ServletContainerInitializers添加filter,调用AbstractFilterRegistrationBean类的addRegistration方法向context添加filter
  2. context中不存在FilterDef则创建对应FilterDef
  3. AbstractFilterRegistrationBean中configure方法添加匹配filter的uri,默认为/*
  4. context启动时,调用filterStart方法配置初始化ApplicationFilterConfig
  5. 调用filter的init方法
  6. 对每次到达的请求在StandardWrapperVavel的invoke方法中创建过滤器链
  7. 根据名称获得ApplicationFilterConfig添加到过滤器链,通过ApplicationFilterConfig来获取filter执行

流程2

  1. ServletContainerInitializer(TomcatStarter实现类).onStartup() 调用 ServletContextInitializer.onStartup(ServletContext)

  2. ServletContextInitializer(AbstractFilterRegistrationBean实现类).onStartup(ServletContext) 调用 ServletContext.addFilter() 方法

  3. ServletContext(ApplicationContext实现类).addFilter 方法调用了 StandandContext.addFilterDef()

  4. StandandContext.addFilterDef() 方法填充 StandandContext.filterDefs

  5. StandandContext.filterStart()

    方法根据 StandandContext.filterDefs属性 填充 StandandContext.filterConfigs

  6. ApplicationFilterFactory根据StandandContext生成filterchain

  7. StandardWrapperValve中调用filterchain.doFilter() 方法

  8. filterchain结束后调用servlet.service方法

思路

  1. 将filterchain放到context中
  2. 每次请求到达从context中获取
  3. filterchain可以复用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值