Owin Katana 的底層原始碼分析

2022-06-29 21:33:14 字數 4525 閱讀 2484

最近看了一下開源專案asp.net katana,感覺公開的介面非常的簡潔優雅,channel 9 說是受到node.js的啟發設計的,katana是乙個比較老的專案,現在已經整合到asp.net core中。

從github轉殖下來的專案,這個部落格專門是從**角度去理解katana專案,所以本篇隨筆針對已經對owin有所了解的人,如果只是入門的話可以跑一下msdn的原始碼再來閱讀本篇文章。

**結構如上,簡單分析一下各個資料夾的含義,這對於理解katana專案的整體結構有乙個大的輪廓。

.build資料夾顧名思義就是編譯的資料夾,在沒使用vs的時候你可以單擊build.cmd 去編譯這個專案,十分的方便。

.nuget就是包管理工具的配置檔案,這個我們可以忽略。同理.prerelease。

development是本次的研究重點,當你開啟這個資料夾的時候你會發現乙個類庫microsoft.owin的類庫,這個是owin元件的經典實現。

functiontests是單元測試的類庫

middleware是一些中介軟體的實現,在katana已經將管道模型虛擬化成中介軟體

performance 和sandbox 是微軟的一些測試工具

security 是微軟已經寫好的驗證中介軟體,其中包括jwt和oauth的驗證方式

server 就是伺服器的實現

owin.analysis是我本人建的web程式用來debug

上面已經介紹了各個資料夾所對應的功能,相必大部分人都是一臉蒙蔽,但是不用擔心,下面就來看看具體的**,當然是從最小的例子出發。點選 getting started with owin and katan 你就能跳到msdn得到最小的例子。裡面的一系列操作就為了新增下面的乙個類和幾個reference.現在我們看一下這個類。

1

using

microsoft.owin;

23 [assembly: owinstartup(typeof

(owin.analysis.startup))]

4namespace

owin.analysis5);

15}16}

17 }

using

system;

using

system.collections.generic;

namespace

owin

//請求的引數

object build(type returntype);//

中介軟體鏈結

建立乙個新的物件

object args);//

註冊中介軟體

}}

public

static

if (handler == null

)

(handler);

}

在經典的實現中,引數middleware會有兩種情況,一種是delegate,一種是type,如果是type型別,則他的構造方法接受next為引數,並且裡面有乙個公開的invoke方法。如果是委託,當前委託作為引數傳遞到next中。

object

args)

下面的**是tomiddlewarefactory的實現,在第9行和第27行分別判斷了中介軟體物件是委託型別還是type型別,由於本題例子是type物件,我們分析一下toconstructormiddlewarefactory方法。

1

private

static tupleobject> tomiddlewarefactory(object middlewareobject, object

args)27

8var middlewaredelegate = middlewareobject as

delegate;

9if (middlewaredelegate != null)10

1314 tupleobject> factory =toinstancemiddlewarefactory(middlewareobject, args);

15if (factory != null)16

1920 factory =togeneratormiddlewarefactory(middlewareobject, args);

21if (factory != null)22

2526

if (middlewareobject is

type)

2730

31throw

new notsupportedexception(string

.format(cultureinfo.currentculture,

32resources.exception_middlewarenotsupported, middlewareobject.gettype().fullname));

33 }

1

2private

static tupleobject> toconstructormiddlewarefactory(object middlewareobject, object args, ref

delegate middlewaredelegate)314

if (!parametertypes

15 .skip(1)16

.zip(args, testargforparameter)

17 .all(x =>x))

1821

22 parameterexpression parameterexpressions = parameters.select(p =>expression.parameter(p.parametertype, p.name)).toarray();

23 newexpression callconstructor =expression.new(constructor, parameterexpressions);

24 middlewaredelegate =expression.lambda(callconstructor, parameterexpressions).compile();

25return tuple.create(parameters[0

].parametertype, middlewaredelegate, args);26}

2728

throw

new missingmethodexception(string

.format(cultureinfo.currentculture,

29 resources.exception_noconstructorfound, middlewaretype.fullname, args.length + 1

));30 }

現在我們重點看一下這個build方法。

public

object

build(type returntype)

build方法呼叫私有的buildinternal的方法。

private

object

buildinternal(type signature)

foreach (var middleware in

_middleware.reverse())

return

}

public

void

}////

null refs for async un-buffered requests with bodies.

}

這裡面有乙個概念就是integratedpipelineblueprintstage,這個是乙個鍊錶結構,每個對應的就是管道事件,每個stage都有entry point,這樣方便我們在不同的管道事件中執行中介軟體,在beginevent裡我們得到stage 的entry point,然後非同步呼叫得到結果。entry point 就是我們上例build得到的結果。

private

catch

(exception ex)

}

然後我們分析一下怎麼在不同的管道中註冊事件。在msdn的文件描述的。

這個api會建立乙個integratedpipelineblueprintstage,上文說這是乙個鍊錶結構,之間用next屬性連線。在不同的stage中會有entry point,然後在上面的例子中註冊到不同的管道中去呼叫。下圖是api的**。

public

stagename)

object

obj;

obj))

return

}

ConcurrentHashMap的原始碼分析

put final v putval k key,v value,boolean onlyifabsent 在上一步的else if中 f 不為null時,則判斷f的hash值是否為moved,即 1,如果為 1,表示正在擴容 else if fh f.hash moved 協助資料遷移 tab h...

DispatcherServlet的原始碼和流程分析

1 自動配置dispatcherservlet和dispatcherservletregistry 2 註冊dispatcherservlet到servletcontext 3 初始化mvc的元件 handler執行完成後,向dispatcherservlet 返回乙個modelandview物件 ...

ConcurrentHashMap底層原始碼實現

concurrenthashmap底層原始碼實現 空構造方法 常用方法put k key,v value 呼叫putval方法 key,value,false putval key,value,false 如果key或者value為空,則丟擲空指標異常,說明不能新增空值 定義hash為hash值sp...