Spring拦截器原理与实战详解

目录

拦截器:

拦截器与过滤器区别

下面是请求发出后的映射过程:

拦截器的入门案例:

第一步:创建一个java类,声明拦截器的bean,并实现HandlerInterceptor接口。

第二步:注册拦截器(不能只创建不使用吧!)

扫描的具体过程:

拦截器的参数;

拦截器链:


前言:当浏览器给我们发送一个请求的时候,请求先到达tomcat服务器,tomcat根据请求来确认这次请求该如何处理。拦截到了所有的请求,然后划分成了静态资源(html页面,CSS,JS等等),(tomcat服务器可以直接给我们)和动态资源,动态资源才是我们要处理的。动态资源不是直接进入到Cotroller层,而是先经过过滤器的筛选,不止一层,,之后才交给我们的处理器去做,中央控制器去会根据请求来判断进入到哪个controller层(将请求分发到具体的控制器当中)当controller执行完后,会返回给浏览器数据。而拦截器就是加在controller层前后的机制。

拦截器:

是一种动态拦截方法调用的机制,在SpringMvc中动态拦截控制器方法的执行。

作用:
++在指定的方法调用前后执行预先设定的代码++

++阻止原始方法的执行++

拦截器与过滤器区别

归属不同:Filter属于Servlet技术,Interceptor属于SpringMVc技术

拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVc的访问进行增强

原理:

拦截器拦截的是请求,可以在请求到达方法前后进行处理

Postman中localhost后面加的是接口地址,这个地址对应后端的一个方法

下面是请求发出后的映射过程:

复制代码
Postman请求: GET http://localhost:8080/api/users/info?id=1001
                    ↓
             DispatcherServlet (前端控制器)
                    ↓
         HandlerMapping (寻找对应的处理器)
                    ↓
             匹配到:@GetMapping("/info")
                    ↓
         HandlerAdapter (适配器,准备调用方法)
                    ↓
           UserController.getUserInfo(1001)
                    ↓
                返回响应

拦截器的入门案例:

第一步:创建一个java类,声明拦截器的bean,并实现HandlerInterceptor接口。

具体操作:

复制代码
// 使用 @Component 注解,将该类声明为一个Spring Bean
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {

    // 在请求到达Controller之前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("LoginInterceptor preHandle...");
        // 返回true表示放行,false表示拦截
        return true; 
    }

    // 在Controller执行之后,视图渲染之前执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("LoginInterceptor postHandle...");
    }

    // 在整个请求完成之后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("LoginInterceptor afterCompletion...");
    }
}

第二步:注册拦截器(不能只创建不使用吧!)

创建一个配置类,实现WebMvcconfigurer接口,并重写addInterceptor方法,将上一步定义的拦截器bean添加到InterceptorRegistry中。重点:这个配置类需要被Spring管理,使用@Configuration注解,

具体操作:

复制代码
// 使用 @Configuration 注解,声明这是一个配置类
@Configuration
public class WebConfig implements WebMvcConfigurer {

    // 自动注入我们定义好的拦截器Bean
    @Autowired
    private LoginInterceptor loginInterceptor;

    // 重写addInterceptors方法,进行注册
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册拦截器,并配置拦截/放行的路径
        registry.addInterceptor(loginInterceptor) // 将拦截器Bean添加到注册中心
                .addPathPatterns("/**")          // 拦截所有请求路径
                .excludePathPatterns("/user/login", "/user/register"); // 放行登录和注册路径

扫描的具体过程:

Spring Boot在启动时,会扫描指定包(通常是主启动类所在包及其子包)下的所有类。它主要扫描两种东西:

  • 带有特定注解的类 :例如 @Component、@Configuration、@Service、@Controller 等。在我们的例子里,LoginInterceptor和WebConfig都被扫描到了。

  • 实现特定接口的类 :例如实现了WebMvcConfigurer接口的类。

  • 当扫描到LoginInterceptor上的@Component时,Spring容器会创建它的一个实例(一个Bean),并管理起来。

  • 当扫描到WebConfig上的@Configuration时,Spring会识别出它是一个配置类,并执行其内部定义好的配置逻辑,特别是重写的addInterceptors方法。

  • 在addInterceptors方法执行时,InterceptorRegistry(拦截器注册表)会拿到我们注入的loginInterceptor Bean,并将它注册到Spring MVC的内部拦截器链中。

最终,当一个请求(比如你在Postman中输入的地址)到达时,Spring MVC的分发器(DispatcherServlet)就会从这个拦截器链中依次调用匹配的拦截器,从而执行我们在LoginInterceptor中定义的preHandle、postHandle等逻辑。

拦截器的参数;

参数 使用场景 主要作用
request 所有方法 获取请求信息(头、参数、IP、URI等)
response preHandle, postHandle 控制响应(状态码、重定向、返回数据)
handler preHandle, postHandle, afterCompletion 获取目标方法信息(控制器、方法、注解)
modelAndView postHandle 操作模型数据和视图(仅页面请求)
exception afterCompletion 处理异常信息

拦截器链:

当配置多个拦截器时,就形成了拦截器链。

执行过程:

最后给大推荐如果您是计算机领域(AI / 大数据 / 网络 / 软件工程等)的研究者,近期有成果想投稿发表,这几个高认可度的国际会议可以参考(均支持 EI/SCOPUS 检索):

第七届计算机信息与大数据应用会议:

https://ais.cn/u/QnaAJz

第九届先进算法与控制工程会议:

https://ais.cn/u/BFfyuq

相关推荐
Decay__7 小时前
05_MySQL 常用 SQL 大全 —— 诊断、管理、优化辅助 SQL 与三大系统库速查
运维·数据库·sql·mysql·架构
贞明电子9 小时前
工业三色报警灯怎么接入项目系统?开关量与RS485控制应用指南
运维·网络·微信公众平台·贞明电子
学长毕设9 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
HideF9 小时前
Linux
linux·服务器·网络
万联WANFLOW9 小时前
海外网络故障怎么排查?Cloudflare 三季度断网报告解读与 mtr 实战
运维·网络·故障分析
zzu123zsw11 小时前
从臃肿的模板调用到声明式契约:深入 UniHttp 动态代理与多渠道生命周期扩展
java·spring boot·microsoft·unihttp
Ruiery11 小时前
Linux 6.6内核内存管理深度解析(十三):slab/slub 分配器
linux·运维·服务器
源码集结号11 小时前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统
论文复现现场12 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
乌恩大侠12 小时前
从 AI-RAN 到 AI Agent:基于 NVIDIA Nemotron 构建 5G/6G 智能网络故障诊断系统
服务器·人工智能·5g·o-ru·ai-ran·电信大模型