亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go-Web框架中AOP方案的實(shí)現(xiàn)方式

 更新時(shí)間:2023年06月05日 11:35:00   作者:今天撿到一百塊錢  
本文主要介紹了Go-Web框架中AOP方案的實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

寫在前面

最近不是在跟兔兔的七天系列嘛,目前是跟到了Web框架(好吧,這才是剛開始)。關(guān)于Web框架這一塊,兔兔的文章是跟完了,也做完了,現(xiàn)在是在做總結(jié)??偨Y(jié)到AOP方案的時(shí)候,就有點(diǎn)蒙圈了,所以打算寫下這篇文章記錄總結(jié)兩種AOP方案。

Gin的AOP實(shí)現(xiàn)方案

其實(shí)兔兔的AOP方案和Gin的AOP方案很相似。都是通過下標(biāo)控制一個(gè)中間件進(jìn)入到下一個(gè)中間件的。當(dāng)下標(biāo)大于中間件的個(gè)數(shù)的時(shí)候,整個(gè)中間件就會(huì)往回執(zhí)行

image.png

特點(diǎn)

  • 中間件是是現(xiàn)在上下文中的
  • 通過下標(biāo)進(jìn)入下一個(gè)中間件

具體看下Gin的實(shí)現(xiàn)源碼

image.png

具體看下兔兔的實(shí)現(xiàn)源碼

image.png

其實(shí)是很類似的。對(duì)于這個(gè)方法,理解起來是沒什么難度的。下面我就講講這個(gè)AOP方案的實(shí)現(xiàn)流程吧。

中間件注冊(cè)是通過Use方法,這個(gè)方法是RouterGroup路由組提供的,在Gin中實(shí)際是抽象出了一個(gè)接口

image.png

image.png

2. 被注冊(cè)的中間件是保存在路由組的屬性中,上圖中圈住的部分

3. 在ServerHTTP方法中匹配命中的路由視圖函數(shù)、符合條件的中間件。

image.png

4. 將命中的視圖函數(shù)添加到中間件列表中

image.png

5. 執(zhí)行Next方法。每當(dāng)中間件函數(shù)中有Next方法,就會(huì)再一次進(jìn)入到Next方法,由于選取要執(zhí)行的中間件是通過c.index控制的,每次進(jìn)來都會(huì)自加1。當(dāng)所有的中間件都執(zhí)行完了,index的值就超過了中間件的個(gè)數(shù)。也就是退出了遞歸。遞歸最底層的方法都執(zhí)行完成了,就開始一層一層返回了。

image.png

責(zé)任鏈制的AOP實(shí)現(xiàn)原理

對(duì)于責(zé)任鏈制的AOP方案,原理和洋蔥模式是一樣,(順帶提一下,Gin的設(shè)計(jì)模式叫做洋蔥模式)。它的任務(wù)是一直構(gòu)建"視圖函數(shù)",最終構(gòu)建成這樣的形式

func m() {
   fmt.Println("coming middleware1...")
   func() {
      fmt.Println("coming middleware2...")
      func() {
         fmt.Println("coming middleware3...")
         func() {
            fmt.Println("coming middleware4...")
            func() {
               fmt.Println("coming middleware5...")
               func() {
               }()
               fmt.Println("outing middleware5...")
            }()
            fmt.Println("outing middleware4...")
         }()
         fmt.Println("outing middleware3...")
      }()
      fmt.Println("outing middleware2...")
   }()
   fmt.Println("outing middleware1...")
}

但是上述這種形式太不優(yōu)雅了,我們就使用一個(gè)責(zé)任鏈的設(shè)計(jì)模式來實(shí)現(xiàn)、優(yōu)化,但是精髓就是構(gòu)建出這種樣子。

image.png

注意

  • 我們需要對(duì)中間件進(jìn)行一個(gè)包裝,就是說對(duì)中間件的函數(shù)簽名進(jìn)行一個(gè)包裝
  • 我們的視圖函數(shù)不用變
  • 可以理解的是中間件函數(shù)就是生成一個(gè)視圖函數(shù),只不過生成的視圖函數(shù)嵌入了一些別的通用邏輯
// 視圖函數(shù)簽名
type HandleFunc func(ctx *Context)
// 中間件函數(shù)簽名
type Middleware func(next HandleFunc) HandeFunc

下文我統(tǒng)一將中間函數(shù)和命中的視圖函數(shù)叫做中間件。不過命中的視圖函數(shù)會(huì)加上特殊二字

中間件函數(shù)簽名解釋一下:

  • 參數(shù)next是下一次需要的中間件邏輯
  • 返回值是一個(gè)特殊的中間件,這個(gè)就是當(dāng)前這個(gè)中間件的邏輯

具體的一個(gè)中間件示例代碼

func Logger() Middleware {
   return func(next HandleFunc) HandleFunc {
       return func(ctx *Context){
           fmt.Println("請(qǐng)求來了")
           next(ctx)
           fmt.Println("請(qǐng)求走了")
       }
   }
}

image.png

解釋示例代碼:

  • Logger函數(shù)返回一個(gè)Middleware函數(shù)。返回一個(gè)視圖函數(shù)構(gòu)造器
  • fmt.Println("請(qǐng)求來了")fmt.Println("請(qǐng)求走了")兩行代碼分別嵌在next下一個(gè)需要執(zhí)行的中間件邏輯

上述已經(jīng)講完了關(guān)于責(zé)任鏈制的AOP方法的具體原理。但是到這里還不夠,這只是原理,還沒有和我們的框架進(jìn)行適配。接下來就具體講講怎么和咱們的框架進(jìn)行適配。

責(zé)任鏈制的AOP方案應(yīng)用

首先還是需要定義好視圖函數(shù)、中間件函數(shù)的簽名

// 視圖函數(shù)簽名
type HandleFunc func(ctx *Context)
// 中間件函數(shù)簽名
type Middleware func(next HandleFunc) HandeFunc

我們的AOP是集成在server層面上的,在Gin中,AOP是集成在Context上下文層面上面的。其實(shí)這個(gè)沒有多大的區(qū)別的,無(wú)非是設(shè)計(jì)者的設(shè)計(jì)思想而已。

說我們的AOP是集成在server層面其實(shí)還不太準(zhǔn)確,準(zhǔn)確來說是在路由組RouterGroup上的。

路由組RouterGroup定義一個(gè)屬性保存當(dāng)前組的所有中間件

image.png

2. 路由組RouterGroup提供一個(gè)方法Use注冊(cè)中間件

image.png

3. 匹配路由的時(shí)候需要找出當(dāng)前路由所屬哪個(gè)組,并將其所有的中間件抽離出來

image.png

4. 組裝中間件

在組裝中間價(jià)的時(shí)候,我們需要注意:

  • 我們注冊(cè)的中間件是有順序的
  • 我們執(zhí)行的中間件也是要有順序的
  • 先注冊(cè)先執(zhí)行前半部分

image.png

基于上述的注意事項(xiàng),我們組裝的中間件應(yīng)該是從后往前組裝的。這里需要花點(diǎn)時(shí)間想想

我們可以這樣想,如果是按照正向的順序遍歷middlewares的話,最后的handler應(yīng)該是最后一個(gè)注冊(cè)的中間件才對(duì)。這和我們的期待是完全相反的,從這也就能解釋為什么我們需要從后往前組裝中間件了。只有這樣,最后handler才是我們第一個(gè)注冊(cè)的中間件方法。

最后就執(zhí)行handler方法即可。

image.png

總結(jié)

  • 基于洋蔥模型的AOP方案和基于責(zé)任鏈制的AOP方案本質(zhì)沒有區(qū)別
  • Gin的AOP是集成在上下文中,我們的是集成在RouterGroup上。兩種方式?jīng)]有區(qū)別

 到此這篇關(guān)于Go-Web框架中AOP方案的實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)Go AOP實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 快速掌握Go語(yǔ)言正/反向代理

    快速掌握Go語(yǔ)言正/反向代理

    這篇文章主要介紹了快速掌握Go語(yǔ)言正/反向代理的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • 使用dep 配置golang 開發(fā)環(huán)境的操作方法

    使用dep 配置golang 開發(fā)環(huán)境的操作方法

    下面小編就為大家?guī)硪黄褂胐ep 配置golang 開發(fā)環(huán)境的操作方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • 詳解Go語(yǔ)言如何解析帶注釋的json

    詳解Go語(yǔ)言如何解析帶注釋的json

    標(biāo)準(zhǔn)的json格式是不帶注釋,但是有時(shí)候?yàn)榱朔奖憷斫鈐son中各字段的含義,需要支持帶注釋的json,這篇文章主要介紹了Go語(yǔ)言解析帶注釋json的相關(guān)方法,希望對(duì)大家有所幫助
    2024-03-03
  • Go 實(shí)現(xiàn)英尺和米的簡(jiǎn)單單位換算方式

    Go 實(shí)現(xiàn)英尺和米的簡(jiǎn)單單位換算方式

    這篇文章主要介紹了Go 實(shí)現(xiàn)英尺和米的簡(jiǎn)單單位換算方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 從零封裝Gin框架實(shí)現(xiàn)日志初始化及切割歸檔功能

    從零封裝Gin框架實(shí)現(xiàn)日志初始化及切割歸檔功能

    這篇文章主要為大家介紹了從零封裝Gin框架實(shí)現(xiàn)日志初始化及切割歸檔功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Go泛型實(shí)戰(zhàn)教程之如何在結(jié)構(gòu)體中使用泛型

    Go泛型實(shí)戰(zhàn)教程之如何在結(jié)構(gòu)體中使用泛型

    這篇文章主要介紹了Go泛型實(shí)戰(zhàn)教程之如何在結(jié)構(gòu)體中使用泛型,根據(jù)Go泛型使用的三步曲提到的:類型參數(shù)化、定義類型約束、類型實(shí)例化我們一步步來定義我們的緩存結(jié)構(gòu)體,需要的朋友可以參考下
    2022-07-07
  • 使用GO操作MongoDB的方法

    使用GO操作MongoDB的方法

    這篇文章主要介紹了使用GO操作MongoDB,包括安裝MongoDB驅(qū)動(dòng)程序連接mongodb的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • Go語(yǔ)言學(xué)習(xí)之Switch語(yǔ)句的使用

    Go語(yǔ)言學(xué)習(xí)之Switch語(yǔ)句的使用

    這篇文章主要通過一些示例為大家介紹一下Go語(yǔ)言中Switch語(yǔ)句的基本語(yǔ)法以及使用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-06-06
  • go panic時(shí)如何讓函數(shù)返回?cái)?shù)據(jù)?

    go panic時(shí)如何讓函數(shù)返回?cái)?shù)據(jù)?

    今天小編就為大家分享一篇關(guān)于go panic時(shí)如何讓函數(shù)返回?cái)?shù)據(jù)?,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • Golang Slice和map的坑

    Golang Slice和map的坑

    Golang中的Slice和Map在內(nèi)存空間上,有一些不同,本文主要介紹了Golang Slice和map的坑,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-04-04

最新評(píng)論