責任鏈(Chain of Responsibility)模式的定義:為了避免請求發送者與多個請求處理者耦合在一起,將所有請求的處理者通過前一對象記住其下一個對象的引用而連成一條鏈;當有請求發生時,可將請求沿著這條鏈傳遞,直到有對象處理它為止。
責任鏈模式也叫職責鏈模式。
在責任鏈模式中,客戶只需要將請求發送到責任鏈上即可,無須關心請求的處理細節和請求的傳遞過程,所以責任鏈將請求的發送者和請求的處理者解耦了。
責任鏈模式是一種對象行為型模式,其主要優點如下。 降低了對象之間的耦合度。該模式使得一個對象無須知道到底是哪一個對象處理其請求以及鏈的結構,發送者和接收者也無須擁有對方的明確信息。 增強了系統的可擴展性??梢愿鶕枰黾有碌恼埱筇幚眍?,滿足開閉原則。 增強了給對象指派職責的靈活性。當工作流程發生變化,可以動態地改變鏈內的成員或者調動它們的次序,也可動態地新增或者刪除責任。 責任鏈簡化了對象之間的連接。每個對象只需保持一個指向其后繼者的引用,不需保持其他所有處理者的引用,這避免了使用眾多的 if 或者 if···else 語句。 責任分擔。每個類只需要處理自己該處理的工作,不該處理的傳遞給下一個對象完成,明確各類的責任范圍,符合類的單一職責原則。
模式結構
職責鏈模式主要包含以下角色: 抽象處理者(Handler)角色:定義一個處理請求的接口,包含抽象處理方法和一個后繼連接。 具體處理者(Concrete Handler)角色:實現抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的后繼者。 客戶類(Client)角色:創建處理鏈,并向鏈頭的具體處理者對象提交請求,它不關心處理細節和請求的傳遞過程。
源碼導讀
在spring security
中其核心設計模式就是責任鏈模式;它通過注冊過濾器鏈來實現責任鏈模式,每個過濾器鏈都只做一件事。springSecurity的責任鏈順序如下
WebAsyncManagerIntegrationFilter:將Security上下文與Spring Web中用于處理異步請求映射的 WebAsyncManager 進行集成。
SecurityContextPersistenceFilter:在每次請求處理之前將該請求相關的安全上下文信息加載到SecurityContextHolder中,然后在該次請求處理完成之后,將SecurityContextHolder中關于這次請求的信 息存儲到一個“倉儲”中,然后將SecurityContextHolder中的信息清除 例如在Session中維護一個用戶的安全信息就是這個過濾器處理的。
HeaderWriterFilter:用于將頭信息加入響應中
CsrfFilter:用于處理跨站請求偽造
LogoutFilter:用于處理退出登錄
UsernamePasswordAuthenticationFilter:用于處理基于表單的登錄請求,從表單中獲取用戶名和密碼。默認情況下處理來自“/login”的請求。從表單中獲取用戶名和密碼時,默認使用的表單name值為“username”和“password”,這兩個值可以通過設置這個過濾器的usernameParameter 和 passwordParameter 兩個參數的值進行修改。
DefaultLoginPageGeneratingFilter:如果沒有配置登錄頁面,那系統初始化時就會配置這個過濾器,并且用于在需要進行登錄時生成一個登錄表單頁面。
BasicAuthenticationFilter:檢測和處理http basic認證
RequestCacheAwareFilter:用來處理請求的緩存
SecurityContextHolderAwareRequestFilter:主要是包裝請求對象request
AnonymousAuthenticationFilter:檢測SecurityContextHolder中是否存在Authentication對象,如果不存在為其提供一個匿名Authentication
SessionManagementFilter:管理session的過濾器
ExceptionTranslationFilter:處理 AccessDeniedException 和 AuthenticationException 異常
FilterSecurityInterceptor:可以看做過濾器鏈的出口
RememberMeAuthenticationFilter:當用戶沒有登錄而直接訪問資源時, 從cookie里找出用戶的信息, 如果Spring Security能夠識別出用戶提供的remember me cookie, 用戶將不必填寫用戶名和密碼, 而是直接登錄進入系統,該過濾器默認不開啟。
而責任鏈的客戶類是HttpSecurity
,它負責對責任鏈的創建和管理,它的addFilterAt(Filter filter, Class atFilter)
方法可在責任鏈中添加一個過濾器。 在這個框架中 過濾器作為了抽象處理者(Handler
的角色,各個具體的過濾器類是具體處理者(Concrete Handler
角色 HttpSecueiry
是客戶類
角色。
本文由博客一文多發平臺 OpenWrite 發布!