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

🥷 一、什么是中间件?

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

  • 选手(请求 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 │
          └───────────────┘

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

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

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

相关推荐
Charlie_lll28 分钟前
力扣解题-移动零
后端·算法·leetcode
打工的小王1 小时前
Spring Boot(三)Spring Boot整合SpringMVC
java·spring boot·后端
80530单词突击赢3 小时前
JavaWeb进阶:SpringBoot核心与Bean管理
java·spring boot·后端
爬山算法3 小时前
Hibernate(87)如何在安全测试中使用Hibernate?
java·后端·hibernate
WeiXiao_Hyy3 小时前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
苏渡苇3 小时前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
long3164 小时前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
rannn_1114 小时前
【苍穹外卖|Day4】套餐页面开发(新增套餐、分页查询、删除套餐、修改套餐、起售停售)
java·spring boot·后端·学习
短剑重铸之日4 小时前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
Dragon Wu5 小时前
Spring Security Oauth2.1 授权码模式实现前后端分离的方案
java·spring boot·后端·spring cloud·springboot·springcloud