ホームページ  >  記事  >  バックエンド開発  >  Jin Engineのソースコードの詳細説明

Jin Engineのソースコードの詳細説明

Golang菜鸟
Golang菜鸟転載
2023-08-04 17:41:43707ブラウズ

ジンとは何ですか?

Gin は、Go (Golang) で書かれた HTTP Web フレームワークです。 Martini に似た API を備えていますが、Martini よりも 40 倍高速に実行されます。極端なパフォーマンスが必要な場合は、ジンを使用してください。

gin なぜ速いのですか?

まずは公式ベンチマークテストを見てみましょうアドレス[1]

Jin Engineのソースコードの詳細説明

これは単なるそのうちの 1 つについては、上記のアドレスで完全版をご自身でご覧いただけます。

パフォーマンス テストから、gin はリクエストの処理パフォーマンスにおいて他の web フレームワークよりも実際にはるかに高速であることがわかります。

パフォーマンスの問題は、主に httprouter[2] を使用することによって発生しますが、httprouterTrie Tree (辞書ツリー) を使用します。 ) 高性能ルックアップを備えたパス ストレージ構造として。

gin.Engine ソース コード

// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
// Create an instance of Engine, by using New() or Default()
type Engine struct {
   RouterGroup       // 用于注册根路由组使用
    ...
    pool             sync.Pool    // 用于 gin.context 对象池
    trees            methodTrees  // 用于保存的请求路径
    ...
}

gin の Engine で最も重要なのは、これら 3 つのフィールドです。

gin.RouterGroup 源码

// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)

// HandlersChain defines a HandlerFunc array.
type HandlersChain []HandlerFunc

// RouterGroup is used internally to configure router, a RouterGroup is associated with
// a prefix and an array of handlers (middleware).
type RouterGroup struct {
    Handlers HandlersChain
    basePath string
    engine   *Engine
    root     bool
}

RouterGroupHandlers存放的是当前分组的所有中间件,也可以说:请求到这个分组,那么Handlers 中的函数都会根据索引从小到大的按顺序执行。

basePath 就是存放这个分组的基础路由路径。可能直接解释过于抽象;我们来分析它的调用链来看:

  1. Jin Engineのソースコードの詳細説明
  2. Jin Engineのソースコードの詳細説明
  3. Jin Engineのソースコードの詳細説明

gin.New() 函数中我们可以看到 basePath 默认是 /Jin Engineのソースコードの詳細説明

而新的RouterGroup是通过Engine调用Group函数产生的;也就是我们自己的Group

Jin Engineのソースコードの詳細説明

那么以后在这个Group注册的路径都会自动加上/user的路径。

为什么会自动添加路径,后面还会分析相关细节。

gin.methodTree 源码

type node struct {
   path      string
   indices   string
   wildChild bool
   nType     nodeType
   priority  uint32
   children  []*node // child nodes, at most 1 :param style node at the end of the array
   handlers  HandlersChain
   fullPath  string
}

type methodTree struct {
    method string
    root   *node
}

type methodTrees []methodTree

对于node的添加和查找我就不展开讲了,如果不懂的可以自行搜索字典树和查看 httprouter[3] 的实现。

我们刚刚在gin.New 函数中可以看到,trees是一个methodTree的切片,并在在初始化给了默认容量为9是容量不是长度哦

Jin Engineのソースコードの詳細説明

addRoute 函数中可以看到trees的添加:

Jin Engineのソースコードの詳細説明

メソッドに対応するルート パス node オブジェクトが存在しない場合は、オブジェクトが作成され、対応するルート登録が追加されます。

#全体プロセス分析

gin フレームワークでは、主に次の登録方法が使用できます。

    #対応する http リクエスト メソッドの名前 (
  • get,post,put...
    )
  • Group
    グループ ルーティングによって削減されます。パスを入力します
  • すべての
  • http
    メソッド ルートをAny
  • これらの登録は実際、これらはすべて同じメソッドを呼び出します。次に、彼女のコートを開いて、中がどのようになっているのか見てみましょう。

Jin Engineのソースコードの詳細説明これらはすべて

group.handle

メソッドという名前であることがわかります。Jin Engineのソースコードの詳細説明このメソッドが何を行うかを見てみましょう:

  • ルーティングのパス計算 group.calculateAbsolutePath(relativePath)
  • 現在登録されているパスにミドルウェア関数を追加して登録しますこの関数は最後に配置されます
  • グローバル ルーティング テーブルに追加します
  • IRoutesInterface
    を返します

combineHandlers サポートされる関数の最大数は 63-1Jin Engineのソースコードの詳細説明

グループ関数

次に、Group の実装を見てみましょう。このメソッドを呼び出すと、パラメーターによって設定された基本パスに基づいて新しい RouterGroup が生成され、 global engine エンティティを作成し、そこに基本的なミドルウェアをコピーします。

Jin Engineのソースコードの詳細説明

グループ ルーティングを使用すると、最終的に group.handle メソッドを呼び出して登録しますが、basePath はグループ化中に設定されています。 、関数を登録するときに追加したパスが、このリクエストのルーティング パスになります。

注意点としては、以前「Group」を使用した後、その後の登録では戻り値を使用していなかった点です登録したルートがどのようにグローバルルーティングテーブルに登録されるのか、ソースを読んで初めて分かりましたコード。

Jin Engineのソースコードの詳細説明

添加路由的时候,是获取的全局engine 实体,所以也是添加到全局路由表中的。

最后需要注意的

在使用注册中间件和注册路由的时候,需要注意他们注册的顺序。

上一点错误的注册方式代码:

package main

import (
 "github.com/gin-gonic/gin"
)

func main() {
 eng := gin.New()
 eng.POST("login", func(context *gin.Context) {
  // 处理登录信息
 })
 eng.Use(gin.Logger())

 userGroup := eng.Group("/user")
 userGroup.GET("info", func(context *gin.Context) {
  // 参数验证

  // 处理逻辑
 })

 adminGroup := eng.Group("/admin")
 adminGroup.GET("info", func(context *gin.Context) {
  // 参数验证

  // 处理逻辑
 })

 eng.Use(gin.Recovery())
 adminGroup.PUT("info", func(context *gin.Context) {
  // 参数验证

  // 处理逻辑
 })
 eng.GET("logout", func(context *gin.Context) {
  // 处理登录信息
 })
 eng.Run(":8080")
}

运行结果:

Jin Engineのソースコードの詳細説明

可以看到在注册路由之后,再注册中间件,那么前面注册过的路由是没有这个中间件的。

以上がJin Engineのソースコードの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はGolang菜鸟で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。