Gin 中间件的核心原理并实现一个简单的中间件框架。Gin 的中间件本质上是基于责任链模式实现的。
以下是一个简化版的中间件框架实现:
package main
import (
"fmt"
"net/http"
)
// 上下文对象
type Context struct {
Writer http.ResponseWriter
Request *http.Request
index int // 当前执行到的中间件索引
handlers []HandlerFunc // 中间件处理函数切片
}
// 处理函数类型
type HandlerFunc func(*Context)
// 创建新的上下文
func newContext(w http.ResponseWriter, r *http.Request) *Context {
return &Context{
Writer: w,
Request: r,
index: -1,
handlers: make([]HandlerFunc, 0),
}
}
// Next 执行下一个中间件
func (c *Context) Next() {
c.index++
for c.index < len(c.handlers) {
c.handlers[c.index](c)
c.index++
}
}
// Engine 框架引擎
type Engine struct {
middleware []HandlerFunc
}
// New 创建新的引擎实例
func New() *Engine {
return &Engine{
middleware: make([]HandlerFunc, 0),
}
}
// Use 添加中间件
func (e *Engine) Use(handler HandlerFunc) {
e.middleware = append(e.middleware, handler)
}
// ServeHTTP 实现 http.Handler 接口
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := newContext(w, r)
c.handlers = e.middleware
c.Next()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package main
import (
"fmt"
"log"
"net/http"
"time"
)
// 日志中间件
func Logger() HandlerFunc {
return func(c *Context) {
start := time.Now()
fmt.Println("Logger 开始")
c.Next()
fmt.Println("Logger 结束")
duration := time.Since(start)
log.Printf("请求处理时间: %v", duration)
}
}
// 认证中间件
func Auth() HandlerFunc {
return func(c *Context) {
fmt.Println("Auth 检查")
// 可以在这里检查认证信息
c.Next()
}
}
// 业务处理
func Business() HandlerFunc {
return func(c *Context) {
fmt.Println("处理业务逻辑")
c.Writer.Write([]byte("Hello, World!"))
}
}
func main() {
// 创建引擎实例
engine := New()
// 注册中间件
engine.Use(Logger())
engine.Use(Auth())
engine.Use(Business())
// 启动服务
http.ListenAndServe(":8080", engine)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
这个实现的关键点:
Context
结构:- 维护请求上下文信息
- 记录当前执行的中间件索引
- 存储所有中间件处理函数
Next
方法:- 类似 Gin 的核心机制
- 通过索引控制中间件的执行顺序
- 实现中间件的链式调用
Engine
结构:- 管理所有中间件
- 实现
http.Handler
接口 - 创建请求上下文并启动中间件链
使用这个框架时的执行顺序:
Logger 开始
Auth 检查
处理业务逻辑
Logger 结束
请求处理时间: xxxms
1
2
3
4
5
2
3
4
5
这个实现虽然简化了很多,但包含了中间件框架的核心概念。Gin 的实现更复杂,包含了更多功能(如路由、参数解析等),但基本原理是类似的。