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中定义的preHandlepostHandle等逻辑。

拦截器的参数;

参数 使用场景 主要作用
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

相关推荐
茶杯梦轩1 小时前
从零起步学习并发编程 || 第一章:初步认识进程与线程
java·服务器·后端
振鹏Dong2 小时前
ReActAgent 源码深度拆解:从调用入口到 ReAct-Loop,读懂智能体 “推理 - 行动” 范式
java·人工智能·spring·ai
QQ 31316378902 小时前
文华财经期货指标公式大全精品套装无未来
java
前路不黑暗@2 小时前
Java项目:Java脚手架项目的模板服务和网关服务的实现(三)
java·开发语言·spring boot·git·学习·spring cloud·maven
远方16092 小时前
114-Oracle Database 26ai在Oracle Linux 9上的OUI图形界面安装
linux·服务器·数据库·sql·oracle·database
heimeiyingwang2 小时前
向量数据库Milvus的安装部署指南
java·数据库·架构·database
马尔代夫哈哈哈2 小时前
SpringBoot 统一功能处理
java·前端·spring boot
开开心心_Every2 小时前
在线看报软件, 22家知名报刊免费看
linux·运维·服务器·华为od·edge·pdf·华为云
BD_Marathon2 小时前
原型模式——Spring源码分析
java·spring·原型模式