首页 > 其他分享 >iris中的中间件调用顺序

iris中的中间件调用顺序

时间:2024-02-07 22:33:53浏览次数:21  
标签:iris 调用 ctx fmt 中间件 next call Println

有一篇文章写得不错:「Go框架」深入理解web框架的中间件运行机制 - 知乎 (zhihu.com)

我这里只是写一个简单的demo来观察一下,代码如下:

package main

import (
    "fmt"

    "github.com/kataras/iris/v12"
    "github.com/kataras/iris/v12/middleware/logger"
    "github.com/kataras/iris/v12/middleware/recover"
)

func GlobalMidware(ctx iris.Context) {
    // 打印消息1
    fmt.Println("GlobalMidware: before call next")
    ctx.Next() //调用下一级handler
    fmt.Println("GlobalMidware: after  call next")
}

// 自定义中间件1:打印消息1
func Middleware1(ctx iris.Context) {
    // 打印消息1
    fmt.Println("Middleware 1: before call next")
    ctx.Next() //调用下一级handler
    fmt.Println("Middleware 1: after  call next")
}

// 自定义中间件2:打印消息2
func Middleware2(ctx iris.Context) {
    // 打印消息2
    fmt.Println("Middleware 2: before call next")
    ctx.Next() //调用下一级handler
    fmt.Println("Middleware 2: after  call next")
}

func MyHandler(ctx iris.Context) {
    fmt.Println("Handler: Hello from handler")
    ctx.HTML("<h1>Hello, World!</h1>")
}

func AdminHelloHandler(ctx iris.Context) {
    fmt.Println("AdminHelloHandler: Hello from handler")
    ctx.HTML("<h1>Hello, Admin!</h1>")
}

func AdminMidware1(ctx iris.Context) {
    // 打印消息2
    fmt.Println("AdminMidware: before call next")
    ctx.Next() //调用下一级handler
    fmt.Println("AdminMidware: after  call next")
}

func AdminRouteMidware(ctx iris.Context) {
    // 打印消息2
    fmt.Println("AdminRouteMidware: before call next")
    ctx.Next() //调用下一级handler
    fmt.Println("AdminRouteMidware: after  call next")
}

func main() {
    app := iris.New()

    // 注册中间件
    app.Use(Middleware1)
    app.Use(Middleware2)

    // 注册默认的恢复中间件
    app.Use(recover.New())

    // 注册默认的日志中间件
    app.Use(logger.New())

    // 路由处理程序
    app.Get("/", MyHandler)

    app.UseGlobal(GlobalMidware)

    apiadmin := app.Party("/admin")
    apiadmin.Use(AdminMidware1)
    apiadmin.UseRouter(AdminRouteMidware)
    apiadmin.Get("/hello", AdminHelloHandler)

    // 启动应用
    app.Run(iris.Addr(":8080"))
}

把程序跑起来之后,用浏览器访问一下 127.0.0.1:8080/admin/hello

可以看到程序有如下输出:

Iris Version: 12.2.0

Now listening on: http://localhost:8080        
Application started. Press CTRL+C to shut down.
AdminRouteMidware: before call next
GlobalMidware: before call next
Middleware 1: before call next
Middleware 2: before call next
AdminMidware: before call next
AdminHelloHandler: Hello from handler
AdminMidware: after  call next
[INFO] 2024/02/07 22:10 200 940.9µs 127.0.0.1 GET /admin/hello
Middleware 2: after  call next
Middleware 1: after  call next
GlobalMidware: after  call next
AdminRouteMidware: after  call next

从这个结果来观察所有handler执行的顺序,可以知道:

1.首先执行的是路由组的Handler,也就是apiadmin.UseRouter(AdminRouteMidware)注册的这个

2.然后执行的是GlobalMidware,在其它所有Midware之前

3.然后执行的是使用Use函数注册的Handler,它们都是同一类型,先注册的先执行

所以,顺序就是Middleware 1、Middleware 2、recover、Logger、AdminMiddleware、

其中recover仅在错误时执行,未体现出来

4.最后执行路由对应的处理函数

其实观察整个调用过程,就是一层一层调用下一个,这也就是ctx.Next()的作用,调用完之后再一层一层返回

了解了这个过程,就知道该如何正确地使用中间件了!

标签:iris,调用,ctx,fmt,中间件,next,call,Println
From: https://www.cnblogs.com/achillis/p/18011422

相关文章

  • 调用大模型实现微信自动回复新年祝福类信息
    调用大模型实现微信自动回复新年祝福类信息一、实现功能通过uiautomation实现自动读取微信(电脑版)未读消息根据关键字判断是否是新春祝福类信息,如果是,调用智谱AI模型,根据接收到的消息,利用模型生成回复内容自动将回复内容发送出去 二、实现效果 三、实现代码fromuiau......
  • 后台没有调用分页方法,但是sql的执行却走了分页
    1、分页方法主要调用PageHelper.startPage()现象:开始是可以查询所有数据,在我调整前台代码以后,SQl查询就变为分页的了。因此,肯定是vue代码有问题,具体为啥前台代码会影响后台的分页呢?很是神奇。(计算机问题,表面上都有神秘的面纱哈哈哈)做法:(1)比对请求参数,发现比原来多了分页参数pa......
  • Java获取方法的调用者
    publicstaticvoidmain(String[]args){method1();}staticvoidmethod1(){method2();}staticvoidmethod2(){method3();}staticvoidmethod3(){printCallingInfo();}staticvoidp......
  • VUE框架CLI组件调用天气接口实现天气界面动态实现和完整工程------VUE框架
    //这句话就等同于我们写的<scriptsrc="vue.js">//这就是在引入vueimportVuefrom'vue';//然后下一步是导入我们的根组件importAppfrom'./App.vue';//导入混入import{mix1}from'./mixin.js';import{mix2}from'./mixin.js';import......
  • Python实例:一个类调用另一个类的方法
    在Python面向对象编程中,类与类之间可以相互交互和调用。本文将介绍如何在一个类中调用另一个类的方法,以实现代码的模块化和复用。一、类与对象简介在Python中,类是一种自定义数据类型,用于封装数据和功能。对象是类的实例,可以通过类创建多个对象。类定义了对象的属性和方法,可以在对象......
  • python怎么调用支持java的接口
    在Python编程中,有时候需要调用支持Java的接口,以实现与Java程序的交互和功能扩展。本文将介绍如何在Python中调用支持Java的接口,以实现跨语言的开发和集成。一、背景知识在Python中,我们可以使用JPype库来实现Python与Java之间的交互。JPype是一个Python模块,提供了Python与Java之间的......
  • FolkMQ "单线程"消息中间件 v1.0.32 发布
    简介采用“单线程”+“多路复用”+"内存运行"+"快照持久化"+"Broker集群模式"(可选)基于Socket.D网络应用协议开发。全新设计,自主架构!角色功能生产端发布消息(Qos0、Qos1)、定时消息(Qos0、Qos1)、可过期消息(Qos0、Qos1)消费端订阅、取消订阅消费......
  • 模块化全局指令调用 - 我的世界OCO指令系列
    最近在搞我的世界指令的模块化。本指令不需要引用任何模块。意义计分板和标签经常作为模块化的入口,然而当我们的操作不具体到实体时,如何才能保证有一个可供我们随意添加标签和计分项目的实体来供我们调用其他模块呢?一个简单的方法是弄一个盔甲架,用特殊的标签标记它,尽量让它......
  • 超简单!手把手实现axum简易中间件
    axum是Rust语言tokio生态中的重要一环,以轻量、模块化、易用而闻名于世。它的中间件系统集成自另一个叫tower的框架,这就意味着如果我们要写axum的中间件的话,就得了解一下这个tower的各个核心概念,并学习它的用法。但是,很多时候我们可能只是想写一点简单的小工具,为了小需求去学习一个......
  • GPT 中的函数调用(function call)是什么?
    在OpenAIChatGPTAPI和GoogleGeminiAPI中我们可以看到函数调用的功能。这个功能是做什么用的?下面大概讲解。以GoogleGeminiAPI函数调用一节中的内容为例,该章节举了一个例子:大语言模型(LLMs)往往无法进行准确的数学运算。比如说,给Gemini两个数\(a\)和\(b\),让它计......