SpringMVC拦截器源码观察

创建拦截器的方式:

方式一:在核心配置文件中配置拦截器组标签里直接创建bean对象

方式二:将拦截器注册到ioc容器中,然后再配置拦截器组标签里引用赋值

但是这两种方式都不能设置拦截的匹配路径,默认都是拦截通过了前端控制器的请求(也就是说,能拦截所有前端控制器所能处理的请求)

方式三,具体配置某个拦截器

在拦截器的匹配路径设置当中的规则:

/*只表示匹配工程目录下的请求,不是所有的请求。/**才是匹配所有的请求

拦截器中的三个抽象方法:

preHandle:在控制器方法执行前执行(它决定了是否对当前请求进行拦截,返回true是放行,返回false是拦截)

postHandle:控制器方法执行之后执行

afterHandle:模板和数据整合完成之后执行

现在我们来看前端控制器是如何使用拦截器的

在doDispatch方法中我们可以看到

 其中拦截器链类的结构为

interceptorIndex应该是:当前执行到的且放行的拦截器索引

初始化拦截器链的构造方法

 我们来看它是如何执行所有拦截器的三个拦截方法的

applyPreHandle方法:

遍历当前的拦截器集合,依次执行当前遍历到的拦截器的preHandle方法,如果返回false,则整个方法直接返回false,前端控制器接收到了false,直接结束doDispatch()方法以达到拦截的目的

而在返回false之前,还调用了执行所有放行的拦截器的after拦截方法

triggerAfterCompletion()用于执行所有放行的拦截器的after拦截方法

applyPostHandle方法:从拦截器集合的末尾往前进行遍历,并调用遍历到的每一个拦截的的postHandle()方法

 

triggerAfterCompletion方法:这个i=this.interceptorIndex就很有意思了,意思是,只遍历当前拦截器集合中没有拦截到请求的的拦截器。换个说法,就是遍历当前请求成功通过的拦截器。

还有具体的生成流程

所以,定义了多个拦截器的时候,按照上下文定义的拦截顺序生成对应的拦截器对象集合

preHandle方法是按集合从前往后执行

postHandle方法,按照集合的size()-1往前执行

afterCompletion方法:按照放行的拦截器逆序执行

因此,从源码看来,

有以上几种情况:假设有两个拦截器A,B(核心配置文件中也是这个顺序)

1、请求被所有的拦截器放行:所有的拦截器的preHandle,postHandle,afterCompletion方法都被执行

2、请求被一些拦截器放行,但是最后被拦截:这里假设请求被A放行,但是被B拦截了。这时候,只执行A的preHandle,B的preHandle,A的afterCompletion

(因为控制器方法根本就没有被执行,所以所有的postHandle不会被执行)

3、请求直接被拦截:

只执行第一个拦截器的preHandle方法

这样看来,afterCompletion方法应该是对进行视图转发前的一些处理而已。同时它如果被调用,就说明通过了当前的拦截器(但不代表请求最后没有被拦截)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孔雀南飞梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值