美文网首页Spring Boot
SpringBoot2.x过滤器OncePerRequestFi

SpringBoot2.x过滤器OncePerRequestFi

作者: 小胖学编程 | 来源:发表于2019-10-25 15:59 被阅读0次

    JAVA && Spring && SpringBoot2.x — 学习目录

    SpringBoot2.x(Spring)含有内置的Filter。即OncePerRequestFilter顾名思义:仅执行一次的Filter。图1是OncePerRequestFilter的子类:

    图1-SpringBoot2.x的OncePerRequestFilter子类关系图.png

    在Spring中,Filter默认继承OncePerRequestFilter类。来过滤请求。

    1. OncePerRequestFilter存在的意义

    OncePerRequestFilter是在一次外部请求中只过滤一次。对于服务器内部之间的forward等请求,不会再次执行过滤方法。

    在SpringBoot2.x环境下,服务器内部转发(forward)一个请求,代码如图2所示:

    图二-转发请求.png
    1. 自定义实现Filter接口的类,在过滤请求时打印日志。结果如图三所示:
    图三-打印Filter请求.png

    根据上图所示,实际上请求在服务器内部转发时,并未进行过滤。可以看到上,实现Filter接口,也会在一次请求中只过滤一次。

    实际上,OncePerRequestFilter是为了兼容不同的web 容器,也就是说其实不是所有的容器都过滤一次。Servlet版本不同,执行的过程也不同。例如:在Servlet2.3中,Filter会过滤一切请求,包括服务器内部使用forward和<%@ include file=/login.jsp%>的情况,但是在servlet2.4中,Filter默认只会过滤外部请求。
    对于异步请求(即为避免线程阻塞,需要委托另一个线程处理),也只过滤一次请求。
    【小家Spring】——关于OncePerRequestFilter

    源码:org.springframework.web.filter.OncePerRequestFilter#doFilter中,通过更改request中的Filter状态,防止内部请求时多次调用Filter,核心代码如图4所示。

    图4-核心源码.png

    采用的是模板方法模式,子类实现org.springframework.web.filter.OncePerRequestFilter#doFilterInternal方法。对请求进行过滤。

    在Spring环境中若想使用Filter,建议继承OncePerRequestFilter,而非原生的Servlet Filter接口。

    2. OncePerRequestFilter方法

    OncePerRequestFilter是采用的模板方法模式,子类需要实现父类定义的钩子方法(算法逻辑父类已经实现),便可以进行过滤。

    2.1 初始化方法

    org.springframework.web.filter.GenericFilterBean#init中实现init方法,子类若是想执行init方法。需要实现org.springframework.web.filter.GenericFilterBean#initFilterBean默认的钩子方法,源码如图5所示。

    图5-init模板方法模式源码.png

    initFilterBean()方法,在两个地方使用到,一个是init方法中,一个是afterPropertiesSet方法(即Filter若放到Spring容器,初始化时执行该方法)。实际上会执行两次初始化方法,如图6所示:

    图6-初始化方法会执行两次.png

    SpringBoot2.x将Filter加入到容器的几种方法

    2.2 过滤方法

    以SpringBoot2.x自动装载的编码过滤器为例,如图7所示:

    源码:org.springframework.web.filter.CharacterEncodingFilter

    图7-CharacterEncodingFilter过滤器核心代码.png

    源码:org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration

    图8-SpringBoot将其加入到容器中.png

    总结:在Spring环境中,推荐实现OncePerRequestFilter类,而非实现原生的Filter接口。

    相关文章

      网友评论

        本文标题:SpringBoot2.x过滤器OncePerRequestFi

        本文链接:https://www.haomeiwen.com/subject/aqlsvctx.html