デザインパターン:Chain of Responsibility Pattern

1.責任連鎖モデルとは何ですか

Chain of Responsibilityモデルでは、複数のプロセッサが同じリクエストを順番に処理します。要求はAプロセッサによって処理され、次にBプロセッサに渡されます。Bプロセッサが処理された後、Cプロセッサに渡され、チェーンが形成されます。チェーン内の各プロセッサは独自の処理責任を負うため、Chain ofResponsibilityモデルと呼ばれます。

GoFによって与えられた定義では、プロセッサチェーン内のプロセッサがこの要求を処理できる場合、要求を引き継ぐことはありません実際、Chain of Responsibilityモデルにはバリエーションがあります。つまり、リクエストはすべてのプロセッサによって処理され、途中で終了することはありません。

ここに画像の説明を挿入

2.コードの実装

1)、リンクリストを使用してプロセッサを格納します

public abstract class Handler {
    
    
    protected Handler nextHandler = null;

    public void setNextHandler(Handler nextHandler) {
    
    
        this.nextHandler = nextHandler;
    }

    public final void handle() {
    
    
        boolean handled = doHandle();
        if (nextHandler != null && !handled) {
    
    
            nextHandler.handle();
        }
    }

    protected abstract boolean doHandle();
}
public class HandlerA extends Handler {
    
    
    @Override
    protected boolean doHandle() {
    
    
        boolean handled = false;
        System.out.println("HandlerA doHandle()");
        return handled;
    }
}
public class HandlerB extends Handler {
    
    
    @Override
    protected boolean doHandle() {
    
    
        boolean handled = false;
        System.out.println("HandlerB doHandle()");
        return handled;
    }
}
public class HandlerChain {
    
    
    private Handler head = null;
    private Handler tail = null;

    public void addHandler(Handler handler) {
    
    
        handler.setNextHandler(null);
        if (head == null) {
    
    
            head = handler;
            tail = handler;
            return;
        }
        tail.setNextHandler(handler);
        tail = handler;
    }

    public void handle() {
    
    
        if (head != null) {
    
    
            head.handle();
        }
    }
}
public class Application {
    
    
    public static void main(String[] args) {
    
    
        HandlerChain chain = new HandlerChain();
        chain.addHandler(new HandlerA());
        chain.addHandler(new HandlerB());
        chain.handle();
    }
}

ハンドラーは、すべてのプロセッサークラスの抽象親クラスでdoHandle()あり、抽象メソッドです。handle()プロセッサーが通過するたびに、要求を処理できる場合は受け渡しを継続しないことを決定します。処理できない場合は、処理します。後続のプロセッサによって処理されます(つまり、call nextHandler.handle())。HandlerChainはプロセッサチェーンです。データ構造の観点からは、チェーンヘッドとチェーンテールを記録するリンクリストです。その中で、レコードチェーンの最後は、プロセッサを追加するのに便利です。

2)、配列を使用してプロセッサを格納します

public interface IHandler {
    
    
    boolean handle();
}
public class HandlerA implements IHandler {
    
    
    @Override
    public boolean handle() {
    
    
        boolean handled = false;
        System.out.println("HandlerA handle()");
        return handled;
    }
}
public class HandlerB implements IHandler {
    
    
    @Override
    public boolean handle() {
    
    
        boolean handled = false;
        System.out.println("HandlerB handle()");
        return handled;
    }
}
public class HandlerChain {
    
    
    private List<IHandler> handlers = new ArrayList<>();

    public void addHandler(IHandler handler) {
    
    
        this.handlers.add(handler);
    }

    public void handle() {
    
    
        for (IHandler handler : handlers) {
    
    
            boolean handled = handler.handle();
            if (handled) {
    
    
                break;
            }
        }
    }
}
public class Application {
    
    
    public static void main(String[] args) {
    
    
        HandlerChain chain = new HandlerChain();
        chain.addHandler(new HandlerA());
        chain.addHandler(new HandlerB());
        chain.handle();
    }
}

3. SpringInterceptorソースコードの分析

カスタムインターセプターは通常、HandlerInterceptorインターフェースのメソッドを実装します。

public interface HandlerInterceptor {
    
    

	default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
    
    

		return true;
	}

	default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {
    
    
	}

	default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
    
    
	}

}
  • preHandle():サービスプロセッサが要求を処理する前に呼び出されます。エンコード、セキュリティ制御、承認検証などのために処理できる前処理。
  • postHandle():ビジネスプロセッサがリクエストを処理して実行した後、ビューが生成される前に実行されます。後処理(サービスが呼び出され、ModelAndViewが返されますが、ページはレンダリングされません)、ModelAndViewを変更する機会があります
  • afterCompletion():DispatcherServletがリクエストを完全に処理した後に呼び出され、リソースのクリーンアップなどに使用できます。返品処理(ページがレンダリングされました)

ここに画像の説明を挿入

Spring Interceptorは、責任チェーンモデルに基づいて実装されます。リクエストの処理フローを上の図に示します。HandlerExecutionChainクラスは、責任チェーンモデルのプロセッサチェーンです。コアコードは次のとおりです。

public class HandlerExecutionChain {
    
    	

	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
    
		HandlerInterceptor[] interceptors = getInterceptors();
		if (!ObjectUtils.isEmpty(interceptors)) {
    
    
			for (int i = 0; i < interceptors.length; i++) {
    
    
				HandlerInterceptor interceptor = interceptors[i];
				if (!interceptor.preHandle(request, response, this.handler)) {
    
    
					triggerAfterCompletion(request, response, null);
					return false;
				}
				this.interceptorIndex = i;
			}
		}
		return true;
	}

	void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
			throws Exception {
    
    

		HandlerInterceptor[] interceptors = 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);
			}
		}
	}

	void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
			throws Exception {
    
    

		HandlerInterceptor[] interceptors = 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 ex2) {
    
    
					logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
				}
			}
		}
	}
}  

おすすめ

転載: blog.csdn.net/qq_40378034/article/details/112732766