Spring Boot一次接口请求涉及的完整执行链路

Spring Boot一次接口请求涉及的完整执行链路


🔁 Spring 项目请求执行链路(简化视图)

text 复制代码
客户端请求(浏览器、Postman)
        ↓
Tomcat(Servlet 容器)
        ↓
【Listener 监听器】
        ↓
【Filter 过滤器】(如安全认证)
        ↓
DispatcherServlet(中央调度器)
        ↓
【HandlerInterceptor 拦截器】
        ↓
【参数解析器(HandlerMethodArgumentResolver)】
        ↓
Controller 方法执行

🧩 各组件详细解析与执行顺序

1️⃣ Listener(Servlet Listener)【最早执行】

  • 监听整个请求生命周期,例如:
    • ServletRequestListener
    • HttpSessionListener
    • ServletContextListener
  • 适合做请求进入/退出日志记录、资源准备等操作

📌【执行时机】:Tomcat 接收到请求,构造 Request 后即触发


2️⃣ Filter(过滤器)【Servlet 级别】

  • 实现 javax.servlet.Filter 接口
  • 是整个请求过程中最早的一环,甚至可以不进入 Spring
  • 常见用途:登录校验、XSS 过滤、CORS 跨域处理等

📌【执行时机】:

  • DispatcherServlet 执行前
  • 可通过 FilterRegistrationBean 控制顺序(@Order@WebFilter

3️⃣ DispatcherServlet(Spring MVC 核心调度器)

  • 核心职责:将请求分发给对应的 Controller
  • 执行顺序如下:
text 复制代码
DispatcherServlet.doDispatch()
  ├─ 处理 Multipart 请求(如文件上传)
  ├─ 调用 HandlerMapping 查找 Controller
  ├─ 调用 HandlerInterceptor.preHandle()
  ├─ 参数解析器(ArgumentResolver)
  ├─ 调用 Controller 方法
  ├─ HandlerInterceptor.postHandle()
  └─ 渲染视图(如 JSON、HTML)

4️⃣ HandlerInterceptor(拦截器)【Spring 层】

  • 实现 HandlerInterceptor 接口
  • 常用于权限校验、日志记录、参数加工等
  • 分为三段生命周期方法:
方法 时机
preHandle Controller 方法
postHandle Controller 方法 ,视图渲染前
afterCompletion 请求全部结束后(包括异常)

📌【执行时机】:由 Spring MVC 控制,必须经过 DispatcherServlet 才会生效


5️⃣ Aspect(AOP 切面)【更精细控制】

  • 使用 @Aspect 实现 AOP,可以控制更细粒度的方法前后逻辑
  • 可用于审计、日志、权限等

📌【执行时机】:真正进入 Controller 方法执行时,环绕通知才会生效

  • 与拦截器的最大区别是,它操作的是方法级别,支持注解切点、参数切点等
  • 可以作用于 Service、Mapper、Controller 等层面

6️⃣ HandlerMethodArgumentResolver(参数解析器)

  • 将 HTTP 参数解析为 Java 方法参数
  • 常见的如 @RequestParam, @PathVariable, @RequestBody 就是由这些解析器完成的

7️⃣ Controller 方法执行

至此,请求真正进入你的业务方法。


🧯 异常处理(ExceptionResolver)

  • 如果 Controller 或任何处理过程中抛出异常,会进入 HandlerExceptionResolver
  • Spring 默认提供:
    • DefaultHandlerExceptionResolver
    • ResponseStatusExceptionResolver
    • ExceptionHandlerExceptionResolver(处理 @ExceptionHandler 注解的方法)

📌 总结执行顺序一览

执行阶段 说明
Listener 请求刚进来,监听请求/会话/上下文
Filter Servlet 层面统一过滤
DispatcherServlet Spring MVC 核心分发器
Interceptor.preHandle 控制器方法执行前,适合权限校验
ArgumentResolver 将参数注入到 Controller 方法中
AOP Around 控制器方法执行前后,可用于埋点日志
Controller 方法 正式执行业务代码
Interceptor.postHandle 方法执行后,视图渲染前
Interceptor.afterCompletion 全流程结束后调用,包括异常情况
ExceptionResolver 统一异常处理

✅ Filter、Interceptor、AOP 区别总览

对比维度 Filter Interceptor(拦截器) AOP(切面)
所属技术 Servlet 规范(JEE 层) Spring MVC Spring AOP(基于代理)
是否依赖 Spring ❌ 无需依赖 Spring ✅ 依赖 Spring MVC ✅ 依赖 Spring(Context + AOP)
拦截对象 所有请求(静态资源也可) Controller 映射方法(Handler) Bean 的方法调用
拦截级别 HTTP 请求级别 MVC 控制器调用前后 方法级别(可拦 Service、DAO、Controller)
是否感知注解 ❌ 无 ✅ 可以读取注解 ✅ 强大注解支持
常见应用 日志打印、CORS、XSS、限流等 登录鉴权、权限控制、日志追踪等 审计日志、事务控制、性能统计、通用逻辑抽取
是否支持链式调用 ✅ FilterChain ✅ 多个拦截器链 ✅ 多个切面 + 顺序控制(@Order)
注册方式 Web.xml 或 Spring Boot 注册 Bean 实现接口 + WebMvcConfigurer 注册 @Aspect 注解 + @EnableAspectJAutoProxy
可用于非 Spring ✅ 是(纯 Servlet 容器可用) ❌ 否(只能在 Spring MVC 项目) ❌ 否(必须由 Spring 管理的 Bean)

📦 Filter 注册方式(Spring Boot)

方式 1:使用 @WebFilter 注解 + @ServletComponentScan

java 复制代码
@WebFilter(urlPatterns = "/*", filterName = "logFilter")
public class LogFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        // 前置处理
        chain.doFilter(request, response); // 放行
        // 后置处理
    }
}

需要在配置类或主启动类上添加:

java 复制代码
@ServletComponentScan

方式 2:使用 Spring Boot 的 FilterRegistrationBean

java 复制代码
@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<LogFilter> logFilter() {
        FilterRegistrationBean<LogFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new LogFilter());
        bean.addUrlPatterns("/*");
        bean.setOrder(1); // 控制执行顺序,值越小越先执行
        return bean;
    }
}

🔗 Interceptor 注册方式(Spring Boot)

java 复制代码
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")  // 拦截路径
                .excludePathPatterns("/login"); // 排除路径
    }
}

拦截器实现:

java 复制代码
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 登录校验逻辑
        return true; // true 放行,false 拦截
    }
}

🔍 AOP 使用与示例

AOP 切面适用于方法级别的增强操作,比如审计日志、数据脱敏、方法耗时统计等。

1. 添加依赖(如果是 Spring Boot 默认 Web 项目已经包含)

xml 复制代码
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 定义切面类

java 复制代码
@Aspect
@Component
public class LogAspect {

    @Pointcut("execution(* com.example.controller..*(..))")
    public void controllerMethods() {}

    @Before("controllerMethods()")
    public void beforeAdvice(JoinPoint joinPoint) {
        // 打印请求信息
    }

    @Around("controllerMethods()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();
        System.out.println("执行耗时:" + (end - start));
        return result;
    }
}

📌 执行顺序对比总结(默认情况)

text 复制代码
↓ 请求进入 ↓
1. Listener(Servlet 容器级别)
2. Filter(全局过滤,早于 Spring)
3. DispatcherServlet
4. Interceptor.preHandle(Spring 拦截器)
5. AOP @Before / @Around(方法增强)
6. Controller 执行
7. AOP @After / @AfterReturning / @AfterThrowing
8. Interceptor.postHandle
9. Interceptor.afterCompletion

🎯 使用建议

目标 推荐使用
全局过滤如跨域、XSS、编码等 Filter
登录认证、权限控制 Interceptor
方法日志、埋点、性能统计 AOP
文件上传前置处理、敏感词替换等 Filter 或 AOP(配合注解)
接口日志记录、签名校验 Interceptor 或 AOP
相关推荐
九转苍翎34 分钟前
Java SE(10)——抽象类&接口
java
明月与玄武34 分钟前
Spring Boot中的拦截器!
java·spring boot·后端
矢鱼34 分钟前
单调栈模版型题目(3)
java·开发语言
n33(NK)41 分钟前
Java中的内部类详解
java·开发语言
为美好的生活献上中指43 分钟前
java每日精进 5.07【框架之数据权限】
java·开发语言·mysql·spring·spring cloud·数据权限
菲兹园长1 小时前
SpringBoot统一功能处理
java·spring boot·后端
muxue1781 小时前
go语言封装、继承与多态:
开发语言·后端·golang
一刀到底2111 小时前
java 多核,多线程,分布式 并发编程的现状 :从本身的jdk ,到 spring ,到其它第三方。
java·分布式·高并发
开心码农1号1 小时前
Go语言中 源文件开头的 // +build 注释的用法
开发语言·后端·golang
北极象1 小时前
Go主要里程碑版本及其新增特性
开发语言·后端·golang