Iris中中间件按注册顺序执行,先注册先执行且需显式调用ctx.Next();Use、Done、UseGlobal作用域与时机不同;ctx.Next()不可跨goroutine调用;中断流程必须用ctx.Stop()。

多个中间件注册顺序决定执行顺序
在 Iris 中,中间件不是“堆叠后统一触发”,而是按注册顺序逐个插入请求处理链。调用 app.Use()、party.Use() 或路由 handler 列表里的函数,都会按写入顺序排进当前作用域的 handler 链。先注册的先执行,且必须显式调用 ctx.Next() 才会进入下一个。
常见错误是以为中间件会自动合并或去重——实际不会。重复调用 Use() 会注册多次,导致同一逻辑执行多遍。
-
app.Use(m1, m2)和app.Use(m1); app.Use(m2)效果等价 - 若在分组上注册:
admin.Use(auth)+admin.Use(logging),则访问/admin/*时先执行auth,再执行logging - 路由级中间件优先级最高:
admin.Get("/x", m3, handler)中的m3会在所有分组中间件之后、handler之前执行
Use / Done / UseGlobal 的作用域和优先级差异
Use、Done、UseGlobal 看似功能相似,但作用域和触发时机完全不同,混用容易导致逻辑错乱或漏执行。
-
Use:只影响该Party(含其子分组)下所有已注册的路由,且在 handler 链开头执行 -
Done:同Use作用域,但在 handler 链末尾执行(即所有 handler 返回后) -
UseGlobal:对所有路由(包括未注册路径产生的 404)都生效,且最先执行——哪怕你没写任何Get或Post,它也会跑
例如:app.UseGlobal(m0) → api.Use(m1) → v1.Get("/x", m2, h),完整执行顺序是:m0 → m1 → m2 → h → (返回后)Done 链(如果注册了)
分组中间件叠加时 ctx.Next() 不可跨 goroutine 调用
中间件里若启动新 goroutine(比如异步记录日志、发通知),切忌在其中调用 ctx.Next()。Iris 的 ctx 对象不是线程安全的,且 Next() 依赖当前 goroutine 的 handler 栈上下文。
- 错误写法:
go func() { ctx.Next() }()—— 极大概率 panic 或静默跳过后续 handler - 正确做法:所有需要
ctx.Next()的逻辑必须在当前 goroutine 同步执行 - 若需异步操作,应在
ctx.Next()之后再启 goroutine,或用ctx.Values().Set()传参,由后续 handler 或Done中统一处理
中间件中提前终止必须用 ctx.Stop(),不能只 return
鉴权、限流、参数校验类中间件常需中断流程。仅 return 是不够的——ctx.Next() 未被调用,但 handler 链仍可能因其他路径继续执行(尤其在分组嵌套场景下)。
- 正确终止:
if !valid { ctx.StatusCode(401); ctx.Stop(); return } -
ctx.Stop()会清空当前 handler 链剩余项,且阻止Done链执行(除非你额外注册了DoneGlobal) - 漏掉
Stop()是 401 响应后仍执行业务 handler 的最常见原因
分组中间件叠加看似简单,但路径拼接、作用域继承、goroutine 安全和终止语义这四点,任意一个出错都会让行为变得不可预测。别依赖“看起来跑通了”,务必在真实路由路径下做端到端验证。


















