为什么说Filter是基于函数回调的?
相信经常查阅博客的朋友们都知道,我们去查阅Filter和Interceptor的区别的文章时,经常有这么一句话:
- 过滤器,依赖于servlet容器,在实现上基于函数回调。
- 拦截器,依赖于依赖于web框架,在实现上基于Java的反射机制,属于面向切面编
程(AOP)的一种运用。
那么为什么说Filter是基于函数回调的呢?函数回调又是怎么回事呢?
函数回调
-
A callback is a function that is passed as an argument to another function and is executed after its parent function has completed。
-
翻译:回调是作为参数传递给另一个函数的函数,在父函数完成后执行。
其实简单点说就是有2个类,A和B,A持有B的引用,当A中调用B的方法时就是回调 即:A(B)
接下来我们就看看Filter的工作图:
FilterChain是Filter的链路,每次url请求过来的时候就会进入链路然后根据事先设定好的Filter顺序按照顺序过滤下去,每次Filter完成了自己的操作后就会调用filterChain.doFilter(servletRequest, servletResponse);将请求发到FilterChain中的下一个Filter处理,如果没有下一个,就直接放行,然后进入servlet获取资源
Filter代码示例:
package com.hxkj.rbac.filter;
import javax.servlet.*;
import java.io.IOException;
/** 字符编码过滤器
* Create by wangbin
* 2019-03-28-14:52
*/
public class EncodingFilter implements Filter {
private String encode;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//Filter初始化
// 读取web.xml中Filter配置的初始化参数
encode = filterConfig.getInitParameter("encode");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 设置初始化的参数encode
servletRequest.setCharacterEncoding(encode);
servletResponse.setCharacterEncoding(encode);
servletResponse.setContentType("text/html; charset=UTF-8");
filterChain.doFilter(servletRequest, servletResponse); // 放行,转到下一个过滤器
}
@Override
public void destroy() {
//在Filter销毁前,完毕某些资源的回收
}
}
从Filter的 doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 这个方法中可以看到,FilterChain作为一个参数传递了进来,
当前的字符过滤Filter将字符编码设置好后,调用了FilterChain的 filterChain.doFilter(servletRequest, servletResponse); 让FilterChain去找下一个Filter进行新的处理,如果没有下一个Filter了,就直接放行,访问servlet获取资源
这就是典型的一个函数回调:
Filter就相当于类A
FilterChain就相当于类B
A(B)
FilterChain作为参数传递给了Filter的doFilter()方法,然后在该方法中又调用了FilterChain的doFilter()方法,即为:函数回调,这也就是为什么说Filter是基于函数回调的原因了
个人理解,如果大家有新的理解欢迎留言。