当前位置:   article > 正文

代码精进之路-设计模式-过滤器链模式_过滤器链设计模式

过滤器链设计模式

7f59ace7a83b2b448a81e334a9ef2159.png

过滤器链设计模式

Java Web应用开发中过滤器Filter都用过,今天老吕带大家来看看最常用的tomcat中是如何实现 Servlet规范中过滤器链功能的。

390a425e7cefe1dac017efc5b9a49809.png

源码讲解

javax.servlet包中关于过滤器的接口

342f2acf149803770e92d5533d09c9d3.png

tomcat的实现过滤器相关的类

8998627e11808b2c166cdf99720935bb.png

主要看这个ApplicationFilterChain类,它实现了FilterChain接口,是关键所在。

为了便于理解代码,我把tomcat源码中和设计模式无关的代码都清理了,只保留下最关键的代码,并加了注释,个别依赖的类也进行了简单处理。

  1. public class ApplicationFilterChain implements FilterChain {
  2. /**
  3. * Filters.
  4. * 过滤器数组集合,初始数组大小为0,这就意味着后面定有扩容操作
  5. */
  6. private Filter[] filters = new Filter[0];
  7. /**
  8. * The int which is used to maintain the current position
  9. * in the filter chain.
  10. * 将要执行的过滤器指针(数组下标)
  11. */
  12. private int pos = 0;
  13. /**
  14. * The int which gives the current number of filters in the chain.
  15. * 过滤器链上过滤器的总数量
  16. */
  17. private int n = 0;
  18. // --------------------------------------------------------------
  19. //过滤器数组扩容容量增量值
  20. public static final int INCREMENT = 10;
  21. /**
  22. * The servlet instance to be executed by this chain.
  23. * 目标servlet,过滤器链执行完毕后直接调
  24. */
  25. private Servlet servlet = null;
  26. @Override
  27. public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
  28. internalDoFilter(request, response);
  29. }
  30. private void internalDoFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
  31. // Call the next filter if there is one
  32. if (pos < n) {
  33. //继续执行下一个过滤器,注意pos的++ 操作,这个是过滤器链指针指向了下一个过滤器,为下一个过滤器的执行做好准备
  34. Filter filter = filters[pos++];
  35. try {
  36. //最后一个参数是关键
  37. //这里面并没有使用for循环把所有的过滤器调用一遍,
  38. //而是用了一个递归操作,通过传递当前FilterChain实例,将调用下下一个过滤器的决定权交给了下一个过滤器
  39. filter.doFilter(request, response, this);
  40. } catch (IOException | ServletException | RuntimeException e) {
  41. throw e;
  42. } catch (Throwable e) {
  43. throw new ServletException("filterChain.filter", e);
  44. }
  45. //如果下一个过滤器忘记了向下传递,就会走到这里,意味着请求的中断
  46. //再也不会调到目标servlet了
    声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/481983
    推荐阅读
    相关标签