赞
踩
过滤器链设计模式
Java Web应用开发中过滤器Filter都用过,今天老吕带大家来看看最常用的tomcat中是如何实现 Servlet规范中过滤器链功能的。
源码讲解
javax.servlet包中关于过滤器的接口
tomcat的实现过滤器相关的类
主要看这个ApplicationFilterChain类,它实现了FilterChain接口,是关键所在。
为了便于理解代码,我把tomcat源码中和设计模式无关的代码都清理了,只保留下最关键的代码,并加了注释,个别依赖的类也进行了简单处理。
- public class ApplicationFilterChain implements FilterChain {
- /**
- * Filters.
- * 过滤器数组集合,初始数组大小为0,这就意味着后面定有扩容操作
- */
- private Filter[] filters = new Filter[0];
-
-
- /**
- * The int which is used to maintain the current position
- * in the filter chain.
- * 将要执行的过滤器指针(数组下标)
- */
- private int pos = 0;
-
-
-
-
- /**
- * The int which gives the current number of filters in the chain.
- * 过滤器链上过滤器的总数量
- */
- private int n = 0;
-
-
- // --------------------------------------------------------------
-
-
- //过滤器数组扩容容量增量值
- public static final int INCREMENT = 10;
-
-
- /**
- * The servlet instance to be executed by this chain.
- * 目标servlet,过滤器链执行完毕后直接调
- */
- private Servlet servlet = null;
-
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
- internalDoFilter(request, response);
- }
-
-
- private void internalDoFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
-
-
- // Call the next filter if there is one
- if (pos < n) {
- //继续执行下一个过滤器,注意pos的++ 操作,这个是过滤器链指针指向了下一个过滤器,为下一个过滤器的执行做好准备
- Filter filter = filters[pos++];
- try {
- //最后一个参数是关键
- //这里面并没有使用for循环把所有的过滤器调用一遍,
- //而是用了一个递归操作,通过传递当前FilterChain实例,将调用下下一个过滤器的决定权交给了下一个过滤器
-
-
- filter.doFilter(request, response, this);
- } catch (IOException | ServletException | RuntimeException e) {
- throw e;
- } catch (Throwable e) {
- throw new ServletException("filterChain.filter", e);
- }
- //如果下一个过滤器忘记了向下传递,就会走到这里,意味着请求的中断
- //再也不会调到目标servlet了 声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/481983推荐阅读
相关标签
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。