本文源碼:GitHub·點這裏 || GitEE·點這裏java
公司常見的請假審批流程:請假天數git
當 day<=3 天,項目經理審批 當 3<day<=5 天,部門經理審批 當 day>5 天,CEO審批
public class C01_InScene { public static void main(String[] args) { // 組裝責任鏈 AuditHandler h1 = new CeoManger(); AuditHandler h2 = new DeptManger(); AuditHandler h3 = new ProjectManger(); h3.setSuccessor(h2); h2.setSuccessor(h1); /* * 測試輸出 * 項目經理無權審批 * 部門經理無權審批 * CEO審批:贊成【Cicada】,請假【6】天 */ h3.handleLeaveDay("Cicada",6); } } abstract class AuditHandler { //持有下一個處理請求的對象 protected AuditHandler successor = null; public AuditHandler getSuccessor() { return successor; } public void setSuccessor(AuditHandler successor) { this.successor = successor; } public abstract void handleLeaveDay (String user,Integer day); } /** * 項目經理審批 */ class ProjectManger extends AuditHandler{ @Override public void handleLeaveDay(String user, Integer day) { if (day <= 3){ System.out.println("項目經理審批:贊成【"+user+"】,請假【"+day+"】天"); } else { System.out.println("項目經理無權審批"); if (getSuccessor() != null){ getSuccessor().handleLeaveDay(user,day); } } } } /** * 部門經理審批 */ class DeptManger extends AuditHandler{ @Override public void handleLeaveDay(String user, Integer day) { if (day > 3 && day <= 5){ System.out.println("部門經理審批:贊成【"+user+"】,請假【"+day+"】天"); } else { System.out.println("部門經理無權審批"); if (getSuccessor() != null){ getSuccessor().handleLeaveDay(user,day); } } } } /** * CEO審批 */ class CeoManger extends AuditHandler{ @Override public void handleLeaveDay(String user, Integer day) { if (day > 5){ System.out.println("CEO審批:贊成【"+user+"】,請假【"+day+"】天"); } else { if (getSuccessor() != null){ getSuccessor().handleLeaveDay(user,day); } } } }
責任鏈模式是一種對象的行爲模式。在責任鏈模式裏,不少對象由每個對象對其下個的引用而鏈接起來造成一條鏈式結構。請求在這個鏈上傳遞,直到鏈上的某一個對象有權處理該請求。請求的客戶端不知道鏈上的哪一個對象處理該請求,這使得系統能夠在不影響客戶端的狀況下動態地從新組織和分配責任對象。github
(1)、抽象處理者角色spring
定義處理請求的接口。接口能夠也能夠給出一個方法以設定和返回對下個對象引用。這個角色一般由一個Java抽象類或者Java接口實現。app
(2)、具體處理者角色框架
具體處理者接到請求後,能夠選擇將請求處理掉,或者將請求傳給下個對象。因爲具體處理者持有對下家的引用。ide
public class C02_Chain { public static void main(String[] args) { // 組裝責任鏈 Handler handler1 = new ConcreteHandler(); Handler handler2 = new ConcreteHandler(); handler1.setHandler(handler2); // 提交請求 handler1.handlerRequest(); } } /** * 抽象處理者角色 */ abstract class Handler { /* * 持有後續的責任對象 */ protected Handler handler; /** * 處理請求的方法 */ public abstract void handlerRequest(); public Handler getHandler() { return handler; } public void setHandler(Handler handler) { this.handler = handler; } } /** * 具體處理者角色 */ class ConcreteHandler extends Handler{ /** * 調用該方法處理請求 */ @Override public void handlerRequest() { /* * 判斷是否有後續的責任對象,沒有就出來請求,有就直接放過 */ if(getHandler() != null){ System.out.println("放過請求,下個對象處理..."); getHandler().handlerRequest(); } else{ System.out.println("直接處理請求了..."); } } }
DispatcherServlet 核心方法 doDispatch。HandlerExecutionChain只是維護HandlerInterceptor的集合,能夠向其中註冊相應的攔截器,自己不直接處理請求,將請求分配給責任鏈上註冊處理器執行,下降職責鏈自己與處理邏輯之間的耦合程度。post
HandlerExecutionChain mappedHandler = null; mappedHandler = this.getHandler(processedRequest); mappedHandler.applyPreHandle(processedRequest, response); mappedHandler.applyPostHandle(processedRequest, response, mv);
這裏分析的幾個方法,都是從DispatcherServlet類的doDispatch方法中請求的。性能
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { HandlerInterceptor[] interceptors = this.getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) { HandlerInterceptor interceptor = interceptors[i]; if (!interceptor.preHandle(request, response, this.handler)) { this.triggerAfterCompletion(request, response, (Exception)null); return false; } } } return true; }
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception { HandlerInterceptor[] interceptors = this.getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for(int i = this.interceptorIndex; i >= 0; --i) { HandlerInterceptor interceptor = interceptors[i]; try { interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable var8) { logger.error("HandlerInterceptor.afterCompletion threw exception", var8); } } } }
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception { HandlerInterceptor[] interceptors = this.getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for(int i = interceptors.length - 1; i >= 0; --i) { HandlerInterceptor interceptor = interceptors[i]; interceptor.postHandle(request, response, this.handler, mv); } } }
GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent