中间件是什么?什么场景使用?

🥷 一、什么是中间件?

中间件就像一条跑道上的检查点

  • 选手(请求 request)跑进来 → 先经过几个检查点(中间件)
  • 每个检查点都可以干点事:查身份证(鉴权)、量血压(数据校验)、拍个照(日志)
  • 最后才到达终点(业务逻辑 Controller)

👉 所以:中间件 = 在请求到达核心逻辑之前/之后插入的一段可复用的小程序


🚦 二、适用场景

中间件特别适合解决"通用但非业务"的问题(专业说法叫 横切关注点 cross-cutting concerns)。

常见的场景有:

  1. 安全保镖类 🛡️

    • 登录校验、权限验证
    • 限流(防止一个人疯狂刷接口)
  2. 服务员类 🍽️

    • 给数据配套餐具(格式化响应,比如统一返回 { code, data, message }
    • CORS 处理(跨域服务)
  3. 记录员类 📒

    • 日志打印(谁在什么时候访问了什么接口)
    • 性能监控(统计耗时)
  4. 修理工类 🔧

    • 捕获错误,统一返回用户友好的信息
    • 请求数据预处理(比如 JSON → 对象,表单 → 参数)

💻 三、代码举例(Express 中间件)

用 Node.js 的 Express 举例,超级直观:

scss 复制代码
const express = require('express');
const app = express();

// 1️⃣ 日志中间件:像"监控摄像头"
function logger(req, res, next) {
  console.log(`[LOG] ${req.method} ${req.url}`);
  next(); // 🚦 放行,交给下一个中间件
}

// 2️⃣ 鉴权中间件:像"门口保安"
function auth(req, res, next) {
  if (!req.headers.authorization) {
    return res.status(401).json({ message: '❌ 未授权' });
  }
  console.log('✅ 授权通过');
  next();
}

// 3️⃣ 统一响应格式中间件:像"餐厅出菜时统一装盘"
function formatResponse(req, res, next) {
  // 重写 res.send 方法
  const oldSend = res.send;
  res.send = function (data) {
    oldSend.call(res, {
      code: 0,
      message: 'success',
      data: data
    });
  };
  next();
}

// 注册中间件(顺序很重要!)
app.use(logger);
app.use(auth);
app.use(formatResponse);

// 核心业务逻辑
app.get('/hello', (req, res) => {
  res.send({ greeting: 'Hello Middleware!' });
});

app.listen(3000, () => {
  console.log('🚀 Server running on http://localhost:3000');
});

执行流程

👉 请求 GET /hello 时:
logger → auth → formatResponse → /hello 控制器 → formatResponse 加工响应 → 返回客户端

就像一条流水线,每个工人(中间件)负责一道工序。


🎯 四、总结

  • 定义:中间件就是请求和业务之间的"拦截器 + 工具人",负责做通用的脏活累活。
  • 适用场景:日志、鉴权、数据预处理、错误捕获、统一响应、跨域......这些和业务没直接关系,但又少不了的地方。
  • 核心价值:让业务逻辑更干净,通用逻辑可复用,可插拔。

流程图(请求 → 多个中间件 → 控制器 → 响应) ,更直观地看到中间件像是"安检流程"的感觉 这就是中间件的流程图 🖼️:

明白啦 👍

我直接给你画出一张清晰的中间件执行流程图(请求和响应都有):

vbscript 复制代码
          ┌───────────────┐
          │   请求 Request │
          └───────┬───────┘
                  │
                  ▼
        ┌─────────────────┐
        │  中间件① 日志    │
        └───────┬─────────┘
                  │
                  ▼
        ┌─────────────────┐
        │  中间件② 鉴权    │
        └───────┬─────────┘
                  │
                  ▼
        ┌────────────────────┐
        │  中间件③ 格式化响应 │
        └───────┬────────────┘
                  │
                  ▼
        ┌───────────────────┐
        │   业务逻辑 Controller │
        └───────┬───────────┘
                  │
         (执行业务并生成响应)
                  │
                  ▼
        ┌────────────────────┐
        │  中间件③ 格式化响应 │
        └───────┬────────────┘
                  │
                  ▼
        ┌─────────────────┐
        │  中间件② 鉴权    │
        └───────┬─────────┘
                  │
                  ▼
        ┌─────────────────┐
        │  中间件① 日志    │
        └───────┬─────────┘
                  │
                  ▼
          ┌───────────────┐
          │   响应 Response │
          └───────────────┘

🔵 ①->③ 方向:请求进来时依次经过各个中间件 → 业务逻辑。

🔴 ③->① 方向:响应出来时再倒序经过中间件 → 返回给客户端。

这样可以看到中间件不仅能预处理请求 ,还能后处理响应

相关推荐
callJJ4 小时前
从 0 开始理解 Spring 的核心思想 —— IoC 和 DI(2)
java·开发语言·后端·spring·ioc·di
你的人类朋友5 小时前
JWT的组成
后端
北风朝向6 小时前
Spring Boot参数校验8大坑与生产级避坑指南
java·spring boot·后端·spring
canonical_entropy7 小时前
一份关于“可逆计算”的认知解码:从技术细节到哲学思辨的完整指南
后端·低代码·deepseek
趙卋傑7 小时前
项目发布部署
linux·服务器·后端·web
数据知道8 小时前
Go基础:Go语言能用到的常用时间处理
开发语言·后端·golang·go语言
不爱编程的小九九9 小时前
小九源码-springboot048-基于spring boot心理健康服务系统
java·spring boot·后端
龙茶清欢9 小时前
Spring Boot 应用启动组件加载顺序与优先级详解
java·spring boot·后端·微服务
2351610 小时前
【LeetCode】3. 无重复字符的最长子串
java·后端·算法·leetcode·职场和发展
可观测性用观测云10 小时前
解锁DQL高级玩法——对日志关键信息提取和分析
后端