拦截器Interceptor
文章目录
前言
本文主要对SpringMVC配置拦截器的方式,xml配置和注解配置,以及对SpringMVC提供的是三个拦截器的执行顺序进行源码性讲解
一、拦截器的三个抽象方法
SpringMVC提供了三个抽象方法
-
preHandle:控制器方法执行之前执行preHandle(),其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法;返回false表示拦截,即不调用控制器方法
-
postHandle:控制器方法执行之后执行postHandle()
-
afterComplation:处理完视图和模型数据,渲染视图完毕之后执行afterComplation()
二、拦截器之XML配置
2.1 需要开启SpringMVC命名空间
// 在beans标签内部添加下列属性
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd"
2.2 ref bean mvc:interceptor三者区别
ref是注入外部bean和直接内部注入bean效果是一样的 都是默认拦截所有请求
mvc:interceptor 则是配置具体拦截请求规则
- mvc-mapping 需要拦截的请求范围
/ 是拦截多层路径的请求 例如 /test/test1**
/则是拦截单层的请求 例如 /test- mvc:exclude-mapping 则是配置不拦截的请求路径映射
- ref在这的作用是使用什么拦截器进行具体的拦截逻辑
<!--配置拦截器-->
<mvc:interceptors>
<ref bean="firstInterceptor" />
<ref bean="secondInterceptor" />
<bean id="firstInterceptor" class="com.worker.mvc.Interceptors.FirstInterceptor"/>
<mvc:interceptor>
<!--/ 只拦截一层路径 /** 拦截多层-->
<mvc:mapping path="/**"/>
<!-- 不拦截主页面 -->
<mvc:exclude-mapping path="/"/>
<ref bean="firstInterceptor"></ref>
</mvc:interceptor>
</mvc:interceptors>
三、拦截器之注解配置
// 7.添加拦截器
// 代替SpringMVC配置文件
@Configuration
// 1.组件扫描
@ComponentScan(basePackages = "com.worker")
// 5.开启注解驱动
@EnableWebMvc // 开启MVC注解驱动
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
FirseInterceptor firseInterceptor = new FirseInterceptor();
registry.addInterceptor(firseInterceptor).addPathPatterns("/**")
.excludePathPatterns("/");
}
}
四、多个拦截器的执行顺序
主要执行逻辑的是DispatcherServlet
- 若每个拦截器的preHandle方法返回为true为放行,preHandle则会根据配置文件的顺序来执行,postHandle和afterComplation则会依照原顺序反着来
- 进入applyPreHandle方法,这里面是正向循环,所以打印的顺序自然也是正向
- if判断中如果interceptor.preHandle返回为true是放行,也就是if不会进入判断去直接执行afterCompletion,而是继续向下执行下一个拦截器
打印内容
- 若某个拦截器的preHandle()返回了false,preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回false的拦截器之前的拦截器的afterComplation()会执行
如果有一个拦截器preHandle返回为false,applyPreHandle的if判断则会进去执行,会直接调用triggerAfterCompletion方法,并返回false
返回false这里就会进去执行if,直接return,后面的拦截器都不会执行
- 这里postHandle循环则是倒叙循环,打印也自然是反序,而这里的interceptorIndex则是此时拦截器最大索引,
- 下面按照顺序自然也是执行到afterCompletion,也就是最后的一个拦截器
打印内容
总结
这里的配置也不是很难,配置也不是很多,主要还是对拦截器的执行,每个人都要有自己的理解和见解,才能懂别人框架的作者是如何设计的这些东西,学会学习别人的好处和优点,加强自己