日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于pipeline

發(fā)布時間:2025/3/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于pipeline 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近要將系統(tǒng)改造成pipeline架構(gòu),所以研究了一下pipeline相關(guān)的理論,servlet filter, struts2 interceptor, spring mvc interceptor, webx pipeline和netty pipeline的一些源碼。一些總結(jié):

結(jié)構(gòu):

  • Pipeline的類模型由Pipeline, Valve 和 Context 組成。 Pipeline代表一個執(zhí)行流,Valve代表執(zhí)行流中的一個節(jié)點,Context是執(zhí)行時的上下文信息,它一般由兩部分組成: request/response + 當前流的執(zhí)行狀態(tài)。

  • 有的系統(tǒng)只能有一個Pipeline, 有的則允許配多個。 在struts2中,一種interceptor的組合,就代表了一個Pipeline;多種組合,意味著多個Pipeline.

  • 用法:

  • 有的pipeline流是在同一層次上,每個valve處理的request/response對象基本上是同質(zhì)的。比如servlet filter和各種mvc框架,所處理的事情都是web層的,所處理的context對象就是http request或框架自定義的javabean.

  • 有的pipeline流則是縱向的,從上層流到下層,或從下層流到上層,這時每個valve所處理的request/response對象一般是異構(gòu)的。協(xié)議棧就是個典型的例子:下層valve處理字節(jié)流,上層Valve處理字符流。 不過,為了適應pipeline架構(gòu),這些異構(gòu)的context對象必須有共同的基類,并且把這個基類作為各個valve的輸入?yún)?shù)。

  • 從請求處理的角度來說, Pipeline可以代表整個執(zhí)行流,也可以只用作請求被最終處理前的Interceptor. Webx, netty中的Pipeline會將最后一個Valve作為請求處理者(一般稱為Request Handler),而servlet filter和struts2 interceptor只作請求攔截、加工,真正的請求處理者則是servlet和action.

  • 程序流:

  • 一個完整的Pipeline執(zhí)行流一般是個環(huán)路: Valve1 => Valve2 => Valve3 => Valve2 => Valve1. 從攔截的角度說,valve既是前置攔截(下一個valve執(zhí)行前),又是后置拉截(下一個 valve執(zhí)行后)。

  • 為了達到前后雙攔截的目標,程序?qū)崿F(xiàn)有兩種方法。 有一種方法是使用forEach方式分別執(zhí)行每個攔截器的前置攔截方法,然后又以相反的順序分別執(zhí)行每個攔截器的后置攔截方法。這種做法比較直觀,可以說直接映射了人類的思考方式。 Spring MVC Interceptor差不多就是這種做法。

  • 另一種做法,也是主流的作法,則會把一個valve的執(zhí)行嵌套在前一個valve的執(zhí)行里面: 每個valve的執(zhí)行中代碼中會有一句"nextValve.invoke()",然后在這句代碼的前后做一些攔截。這種方式有點費解,而且由于嵌套過多容易造成比較深的調(diào)用棧。 不過它有一個好處: 更方便地中斷執(zhí)行流并處理異常(下詳)。

  • 執(zhí)行流須提供中斷機制和異常處理機制,比如一個鑒權(quán)filter在發(fā)現(xiàn)用戶未登錄時需要立即返回403并中斷流,當一個valve出現(xiàn)異常時這個異常需要被捕捉、處理。 如果Valve是嵌套執(zhí)行的,這些機制會很方便實現(xiàn): 鑒權(quán)filter發(fā)現(xiàn)用戶未登錄時,不調(diào)用nextValve.invoke()即可中斷pipeline; 至于異常處理,Struts2默認使用ExceptionMappingInterceptor作為Pipeline中的第1個valve, 它會把nextIntercetpor.invoke()放在自己的try/catch塊中。如果valve不是嵌套執(zhí)行,而是由pipeline通過forEach編排執(zhí)行的,那么這些非正常流的“扳道工”職責就必須由pipeline自己來承擔, 這可能會使pipeline不夠精簡;如果來了新的邏輯(比如異步執(zhí)行),又得改pipeline,導致pipeline不太穩(wěn)定。

  • 設(shè)計模式:

    狀態(tài)/無狀態(tài), 單例/非單例. 如果不怕麻煩,可以每來一個請求,就生成一個Pipeline對象和一堆Valve對象,再把request和上下文信息用作這些對象的狀態(tài);但是,用單例的風格更符合當代程序員的習慣,也更容易與spring結(jié)合。 那么,全單例并且都是無狀態(tài)? 不盡然。雖然Pipeline的結(jié)構(gòu)本身是靜態(tài)的,一個pipeline結(jié)構(gòu)可以作成一個單例;但Pipeline的執(zhí)行流是有狀態(tài)的,比如當前執(zhí)行到了哪個valve,是需要一個變量來維護的。 所以,可以做一個單例的對象Pipeline, 代表Pipeline的結(jié)構(gòu);另做一個對象PipelineContext,代表Pipeline當前的執(zhí)行流;至于Valve,它相當于一個stateless service, 做成單例即可.

    轉(zhuǎn)載于:https://www.cnblogs.com/wdmx/p/9895015.html

    總結(jié)

    以上是生活随笔為你收集整理的关于pipeline的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。