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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

java设计模式之责任链模式以及在java中作用

發布時間:2023/12/18 asp.net 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java设计模式之责任链模式以及在java中作用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

責任鏈模式是一種對象的行為模式。在責任鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發出這個請求的客戶端并不知道鏈上的哪一個對象最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新組織和分配責任。

純的與不純的責任鏈模式

  一個純的責任鏈模式要求一個具體的處理者對象只能在兩個行為中選擇一個:一是承擔責任,而是把責任推給下家。不允許出現某一個具體處理者對象在承擔了一部分責任后又 把責任向下傳的情況。

  在一個純的責任鏈模式里面,一個請求必須被某一個處理者對象所接收;在一個不純的責任鏈模式里面,一個請求可以最終不被任何接收端對象所接收。

  純的責任鏈模式的實際例子很難找到,一般看到的例子均是不純的責任鏈模式的實現。有些人認為不純的責任鏈根本不是責任鏈模式,這也許是有道理的。但是在實際的系統里,純的責任鏈很難找到。如果堅持責任鏈不純便不是責任鏈模式,那么責任鏈模式便不會有太大意義了。

責任鏈模式在Tomcat中的應用

  眾所周知Tomcat中的Filter就是使用了責任鏈模式,創建一個Filter除了要在web.xml文件中做相應配置外,還需要實現javax.servlet.Filter接口。

public class TestFilter implements Filter{public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {chain.doFilter(request, response);}public void destroy() {}public void init(FilterConfig filterConfig) throws ServletException {}}

  使用DEBUG模式所看到的結果如下

  其實在真正執行到TestFilter類之前,會經過很多Tomcat內部的類。順帶提一下其實Tomcat的容器設置也是責任鏈模式,注意被紅色方框所圈中的類,從Engine到Host再到Context一直到Wrapper都是通過一個鏈傳遞請求。被綠色方框所圈中的地方有一個名為ApplicationFilterChain的類,ApplicationFilterChain類所扮演的就是抽象處理者角色,而具體處理者角色由各個Filter扮演。

  第一個疑問是ApplicationFilterChain將所有的Filter存放在哪里?

  答案是保存在ApplicationFilterChain類中的一個ApplicationFilterConfig對象的數組中。

?

那ApplicationFilterConfig對象又是什么呢?

 ?? ApplicationFilterConfig是一個Filter容器。

?

當一個web應用首次啟動時ApplicationFilterConfig會自動實例化,它會從該web應用的web.xml文件中讀取配置的Filter的信息,然后裝進該容器。

  剛剛看到在ApplicationFilterChain類中所創建的ApplicationFilterConfig數組長度為零,那它是在什么時候被重新賦值的呢?

private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];

  是在調用ApplicationFilterChain類的addFilter()方法時。

?

 變量n用來記錄當前過濾器鏈里面擁有的過濾器數目,默認情況下n等于0,ApplicationFilterConfig對象數組的長度也等于0,所以當第一次調用addFilter()方法時,if?(n?==?filters.length)的條件成立,ApplicationFilterConfig數組長度被改變。之后filters[n++] =?filterConfig;將變量filterConfig放入ApplicationFilterConfig數組中并將當前過濾器鏈里面擁有的過濾器數目+1。

  那ApplicationFilterChain的addFilter()方法又是在什么地方被調用的呢?

  是在ApplicationFilterFactory類的createFilterChain()方法中。

?

可以將如上代碼分為兩段,51行之前為第一段,51行之后為第二段。

  第一段的主要目的是創建ApplicationFilterChain對象以及一些參數設置。

  第二段的主要目的是從上下文中獲取所有Filter信息,之后使用for循環遍歷并調用filterChain.addFilter(filterConfig);將filterConfig放入ApplicationFilterChain對象的ApplicationFilterConfig數組中。

  那ApplicationFilterFactory類的createFilterChain()方法又是在什么地方被調用的呢?

  是在StandardWrapperValue類的invoke()方法中被調用的。

  

 那正常的流程應該是這樣的:

  在StandardWrapperValue類的invoke()方法中調用ApplicationFilterChai類的createFilterChain()方法———>在ApplicationFilterChai類的createFilterChain()方法中調用ApplicationFilterChain類的addFilter()方法———>在ApplicationFilterChain類的addFilter()方法中給ApplicationFilterConfig數組賦值。

  根據上面的代碼可以看出StandardWrapperValue類的invoke()方法在執行完createFilterChain()方法后,會繼續執行ApplicationFilterChain類的doFilter()方法,然后在doFilter()方法中會調用internalDoFilter()方法。

?

這里的filter.doFilter(request, response,?this);就是調用我們前面創建的TestFilter中的doFilter()方法。而TestFilter中的doFilter()方法會繼續調用chain.doFilter(request, response);方法,而這個chain其實就是ApplicationFilterChain,所以調用過程又回到了上面調用dofilter和調用internalDoFilter方法,這樣執行直到里面的過濾器全部執行。

  由于invoke()方法較長,所以將很多地方省略。

轉載于:https://www.cnblogs.com/kisty/p/6135029.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的java设计模式之责任链模式以及在java中作用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。