shiro过滤器链和web容器过滤器链(2)

在这里插入图片描述
接着上一篇文章https://blog.csdn.net/weixin_41490593/article/details/90055562

当请求到tomcat过滤器链中的ShiroFilterFactoryBean时,它是AbstractShiroFilter过滤器,
由于AbstractShiroFilter又继承OncePerRequestFilter类
所以当执行tomcat过滤器链中的ShiroFilterFactoryBean本身时,就是调用ShiroFilterFactoryBean的doFilter方法,由于AbstractShiroFilter是没有doFilter方法,所以调用父类OncePerRequestFilter的doFilter方法
而doFilter方法中,有一句代码

this.doFilterInternal(request, response, filterChain);

这个doFilterInternal()方法是OncePerRequestFilter留给子类实现的,所以当这个方法执行的时候,就回到了AbstractShiroFilter中的doFilterInternal()方法

而AbstractShiroFilter中doFilterInternal()方法的执行就是从shiro启动时创建的众多过滤器链中找匹配当前请求uri的一条过滤器链,然后创建一个代表当前shiro过滤器链的代理过滤器链ProxiedFilterChain

当执行这条shiro过滤器链中的一个shiro过滤器时,由于这链中的过滤器是实现AccessControlFilter的,是在OncePerRequestFilter的AdviceFilter过滤器分支下的,
当执行过滤器时,由于没有doFilter方法,会回到OncePerRequestFilter类中,执行doFilter.

而执行OncePerRequestFilter中doFilter方法时,执行到doFilterInternal()方法,这个方法是留给子类执行的,所以,这时是进入到了AdviceFilter分支下,执行AdviceFilter中的doFilterInternal()方法

AdviceFilter是类似springmvc拦截器,在过滤器前后做点什么,可留给AdviceFilter的子类覆盖其preHandle方法和postHandle方法

AdviceFilter的直接子类有PathMatchingFilter和LogoutFilter,覆盖了preHandle方法
因为AccessControlFilter是在PathMatchingFilter下的,而一般自定义过滤器继承AccessControlFilter,所以选择PathMatchingFilter的preHandle方法说明.
在PathMatchingFilter的preHandle方法中,跟踪代码知道

this.onPreHandle(request, response, pathConfig);

而由于子类AccessControlFilter覆盖了父类PathMatchingFilter的onPreHandle方法,所以调用子类AccessControlFilter的onPreHandle方法

public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
    return this.isAccessAllowed(request, response, mappedValue) || this.onAccessDenied(request, response, mappedValue);
}

自定义的继承AccessControlFilter的过滤器中有两个方法就是从这里调用的
isAccessAllowed方法返回false就调用onAccessDenied方法,否则通过

补充知识:
如果创建的自定义shiro过滤器,如果作为bean给springIOC容器的话,自定义的shiro过滤器会在tomcat过滤器链中也会有一份,这时就会出现执行完了shiro过滤器链后,有重复执行自定义shiro过滤器现象.这是因为tomcat过滤器链中也有一份了.

补充第一篇文章的遗留问题:
就是shiro把tomcat的request和response包装后,除了在springmvc的Controller中获取是包装的,在其他地方,如service层借用spring提供的工具获取request和response,是被shiro包装后的么?
答案:是

猜你喜欢

转载自blog.csdn.net/weixin_41490593/article/details/90067018