【SpringMVC】SpringMVC之拦截器Interceptor

拦截器Interceptor



在这里插入图片描述

前言

本文主要对SpringMVC配置拦截器的方式,xml配置和注解配置,以及对SpringMVC提供的是三个拦截器的执行顺序进行源码性讲解


一、拦截器的三个抽象方法

SpringMVC提供了三个抽象方法

  1. preHandle:控制器方法执行之前执行preHandle(),其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法;返回false表示拦截,即不调用控制器方法

  2. postHandle:控制器方法执行之后执行postHandle()

  3. 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 则是配置具体拦截请求规则

  1. mvc-mapping 需要拦截的请求范围
    / 是拦截多层路径的请求 例如 /test/test1**
    /则是拦截单层的请求 例如 /test
  2. mvc:exclude-mapping 则是配置不拦截的请求路径映射
  3. 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
在这里插入图片描述

  1. 若每个拦截器的preHandle方法返回为true为放行,preHandle则会根据配置文件的顺序来执行,postHandle和afterComplation则会依照原顺序反着来

请添加图片描述

  1. 进入applyPreHandle方法,这里面是正向循环,所以打印的顺序自然也是正向
  2. if判断中如果interceptor.preHandle返回为true是放行,也就是if不会进入判断去直接执行afterCompletion,而是继续向下执行下一个拦截器

打印内容
请添加图片描述

  1. 若某个拦截器的preHandle()返回了false,preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回false的拦截器之前的拦截器的afterComplation()会执行

如果有一个拦截器preHandle返回为false,applyPreHandle的if判断则会进去执行,会直接调用triggerAfterCompletion方法,并返回false
在这里插入图片描述
返回false这里就会进去执行if,直接return,后面的拦截器都不会执行
在这里插入图片描述

  1. 这里postHandle循环则是倒叙循环,打印也自然是反序,而这里的interceptorIndex则是此时拦截器最大索引,
  2. 下面按照顺序自然也是执行到afterCompletion,也就是最后的一个拦截器

打印内容
在这里插入图片描述


总结

这里的配置也不是很难,配置也不是很多,主要还是对拦截器的执行,每个人都要有自己的理解和见解,才能懂别人框架的作者是如何设计的这些东西,学会学习别人的好处和优点,加强自己

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值