最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

寫(xiě)在前面

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

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

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

image.png

特點(diǎn)

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

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

image.png

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

image.png

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

中間件注冊(cè)是通過(guò)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í)行的中間件是通過(guò)c.index控制的,每次進(jìn)來(lái)都會(huì)自加1。當(dāng)所有的中間件都執(zhí)行完了,index的值就超過(guò)了中間件的個(gè)數(shù)。也就是退出了遞歸。遞歸最底層的方法都執(zhí)行完成了,就開(kāi)始一層一層返回了。

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ì)模式來(lái)實(shí)現(xiàn)、優(yōu)化,但是精髓就是構(gòu)建出這種樣子。

image.png

注意

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

下文我統(tǒng)一將中間函數(shù)和命中的視圖函數(shù)叫做中間件。不過(guò)命中的視圖函數(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)求來(lái)了")
           next(ctx)
           fmt.Println("請(qǐng)求走了")
       }
   }
}

image.png

解釋示例代碼:

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

上述已經(jīng)講完了關(guān)于責(zé)任鏈制的AOP方法的具體原理。但是到這里還不夠,這只是原理,還沒(méi)有和我們的框架進(jìn)行適配。接下來(lái)就具體講講怎么和咱們的框架進(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è)沒(méi)有多大的區(qū)別的,無(wú)非是設(shè)計(jì)者的設(shè)計(jì)思想而已。

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

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

image.png

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

image.png

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

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ì)沒(méi)有區(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)文章

  • Golang error使用場(chǎng)景介紹

    Golang error使用場(chǎng)景介紹

    我們?cè)谑褂肎olang時(shí),不可避免會(huì)遇到異常情況的處理,與Java、Python等語(yǔ)言不同的是,Go中并沒(méi)有try...catch...這樣的語(yǔ)句塊,這個(gè)時(shí)候我們?nèi)绾尾拍芨玫奶幚懋惓D??本文?lái)教你正確方法
    2023-03-03
  • Go語(yǔ)言處理超大字符串型整數(shù)加減經(jīng)典面試詳解

    Go語(yǔ)言處理超大字符串型整數(shù)加減經(jīng)典面試詳解

    這篇文章主要為大家介紹了Go語(yǔ)言處理超大字符串型整數(shù)加減經(jīng)典面試示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Go開(kāi)源項(xiàng)目分布式唯一ID生成系統(tǒng)

    Go開(kāi)源項(xiàng)目分布式唯一ID生成系統(tǒng)

    這篇文章主要為大家介紹了Go開(kāi)源項(xiàng)目分布式唯一ID生成系統(tǒng)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Go語(yǔ)言中slice類(lèi)型的使用小結(jié)

    Go語(yǔ)言中slice類(lèi)型的使用小結(jié)

    本文主要介紹了Go語(yǔ)言中slice類(lèi)型的使用小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-03-03
  • Golang 之區(qū)分類(lèi)型別名與類(lèi)型定義的方法

    Golang 之區(qū)分類(lèi)型別名與類(lèi)型定義的方法

    這篇文章主要介紹了Golang 之區(qū)分類(lèi)型別名與類(lèi)型定義的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • go?map搬遷的實(shí)現(xiàn)

    go?map搬遷的實(shí)現(xiàn)

    本文主要介紹了go?map搬遷的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 深入探究Go語(yǔ)言從反射到元編程的實(shí)踐與探討

    深入探究Go語(yǔ)言從反射到元編程的實(shí)踐與探討

    反射和元編程是一些高級(jí)編程概念,它們使開(kāi)發(fā)者能夠在運(yùn)行時(shí)檢查、修改并控制程序的行為,了解反射和元編程的工作方式可以幫助我們更好地理解Go,以及如何在需要的時(shí)候高效地使用它們,文章中介紹的非常詳細(xì),感興趣的同學(xué)可以參考下
    2023-05-05
  • GoFrame基于性能測(cè)試得知grpool使用場(chǎng)景

    GoFrame基于性能測(cè)試得知grpool使用場(chǎng)景

    這篇文章主要為大家介紹了GoFrame基于性能測(cè)試得知grpool使用場(chǎng)景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 一文探索Go語(yǔ)言中的內(nèi)存對(duì)齊

    一文探索Go語(yǔ)言中的內(nèi)存對(duì)齊

    在 Go 語(yǔ)言中,內(nèi)存對(duì)齊是一個(gè)經(jīng)常被忽略但非常重要的概念,本文將通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)探討 Go 語(yǔ)言中的內(nèi)存對(duì)齊機(jī)制,感興趣的可以了解下
    2024-11-11
  • Golang開(kāi)發(fā)之字符串與切片問(wèn)題踩坑記錄

    Golang開(kāi)發(fā)之字符串與切片問(wèn)題踩坑記錄

    字符串和切片,都是golang常用的兩種內(nèi)置數(shù)據(jù)類(lèi)型,最近在日常工作中,遇到了一個(gè)字符串切片導(dǎo)致的問(wèn)題,記錄一下排查問(wèn)題的過(guò)程,避免后續(xù)在這種場(chǎng)景上踩坑
    2023-07-07

最新評(píng)論

达拉特旗| 福建省| SHOW| 平顶山市| 临沧市| 台中市| 中卫市| 阳原县| 鸡泽县| 东光县| 日喀则市| 庆云县| 连山| 金寨县| 孝昌县| 揭阳市| 兴仁县| 启东市| 江口县| 通化市| 通海县| 阿拉尔市| 乐昌市| 红桥区| 宝坻区| 余庆县| 苗栗市| 抚顺市| 和平区| 祥云县| 奈曼旗| 肥乡县| 醴陵市| 宝清县| 饶平县| 出国| 佛坪县| 永川市| 克山县| 南江县| 扎兰屯市|