欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入了解Java設(shè)計模式之職責(zé)鏈模式

 更新時間:2022年09月07日 16:51:53   作者:小小張自由—>張有博  
Java設(shè)計模式中有很多種類別,例如單例模式、裝飾模式、觀察者模式等。本文將為大家詳細(xì)介紹其中的職責(zé)鏈模式,感興趣的可以了解一下

定義

使多個對象都有機會處理請求,從而避免請求的發(fā)送者和接受者之間的耦合關(guān)系,將這個對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止。

解決的問題

請求和處理分開、實現(xiàn)解耦、提高系統(tǒng)的靈活性

可以動態(tài)的調(diào)整請求的鏈條,增加系統(tǒng)靈活性

核心要點

職責(zé)鏈模式每個執(zhí)行者都包含了另一個執(zhí)行者的引用。如果一個對象不能處理該請求,會把請求傳遞給下一個執(zhí)行者。

客戶端需要動態(tài)的調(diào)整,執(zhí)行者的上下級。

Handler 里面聚合它自己,在 HandlerRequest 里判斷是否合適,如果沒達(dá)到條件則向下傳遞,向誰傳遞之前 set 進去。

類圖

代碼實現(xiàn)

抽象父類

/**
 * 處理請求的抽象類
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/7 - 9:29
 */
public abstract class Handler {

    //維持一個下一個執(zhí)行者的引用
    protected Handler handler;
    
    protected void setHandler(Handler handler) {
        this.handler = handler;
    }

    //處理請求的抽象方法
    public abstract void  processRequest(int request);
}

執(zhí)行者-三個

/**
 *  只處理數(shù)字1-10
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/7 - 9:31
 */
public class ConcreteHandlerA extends Handler{
    @Override
    public void processRequest(int request) {
        if (request>=0 && request<10 ){
            System.out.println("ConcreteHandlerA已經(jīng)處理完畢了  "+request);
            return;
        }
        if (handler!=null){
            //下一位處理
            handler.processRequest(request);
        }
    }
}

/**
 * 只處理數(shù)字10-20
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/7 - 9:31
 */
public class ConcreteHandlerB extends Handler{
    @Override
    public void processRequest(int request) {
        if (request>=10 && request<20 ){
            System.out.println("ConcreteHandlerB已經(jīng)處理完畢了  "+request);
            return;
        }
        if (handler!=null){
            //下一位處理
            handler.processRequest(request);
        }
    }
}

/**
 *只處理數(shù)字30+
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/7 - 9:31
 */
public class ConcreteHandlerC extends Handler{
    @Override
    public void processRequest(int request) {
        if (request>=30 ){
            System.out.println("ConcreteHandlerC已經(jīng)處理完畢了  "+request);
            return;
        }
        if (handler!=null){
            //下一位處理
            handler.processRequest(request);
        }
    }
}

客戶端

public class Main {

    public static void main(String[] args) {
        //創(chuàng)建執(zhí)行者
        Handler h1=new ConcreteHandlerA();
        Handler h2=new ConcreteHandlerB();
        Handler h3=new ConcreteHandlerC();

        //設(shè)置向下級的順序,可根據(jù)配置動態(tài)設(shè)置上下級
        h1.setHandler(h2);
        h2.setHandler(h3);
        int[] requests={8,11,23,50,7,19,28,40};

        //循環(huán)處理請求,不同的數(shù)值,交給不同的執(zhí)行者
        for (int request : requests) {

            h1.processRequest(request);
        }
    }

}

拓展

SpringMVC中DispatchServlet使用職責(zé)鏈

 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;//請求
        HandlerExecutionChain mappedHandler = null;//執(zhí)行鏈

        try {
            ModelAndView mv = null;
            Exception dispatchException = null;

            try {

                // Determine handler for the current request.
                mappedHandler = getHandler(processedRequest); //根據(jù)請求-獲得執(zhí)行鏈
                //判斷mappedHandler是否為空,空:404
                if (mappedHandler == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }

                // 確定當(dāng)前請求的處理程序適配器
                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                //職責(zé)鏈的前置攔截
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                //執(zhí)行handler方法-controller
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                //職責(zé)鏈的后置攔截
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            }
            catch (Exception ex) {
                dispatchException = ex;
            }
            //對結(jié)果集進行處理
            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        }
        catch (Exception ex) {
            //執(zhí)行完成了攔截器
            triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
        }
       
        finally {
            //資源釋放 
        }
    }

攔截器的方法

	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HandlerInterceptor[] interceptors = getInterceptors(); //獲得攔截器
		if (!ObjectUtils.isEmpty(interceptors)) {
			for (int i = 0; i < interceptors.length; i++) {//循環(huán)遍歷執(zhí)行前置攔截
				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--) { //循環(huán)遍歷執(zhí)行后置攔截
				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 {   //循環(huán)遍歷執(zhí)行完成攔截
					interceptor.afterCompletion(request, response, this.handler, ex);
				}
				catch (Throwable ex2) {
					logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
				}
			}
		}
	}

應(yīng)用場景

1、有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定。

2、在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。

3、可動態(tài)指定一組對象處理請求。

4、比如:JS 中的事件冒泡,JAVA WEB 中 Apache Tomcat 對 Encoding 的處理,Struts2 的攔截器,jsp servlet 的 Filter。

到此這篇關(guān)于深入了解Java設(shè)計模式之職責(zé)鏈模式的文章就介紹到這了,更多相關(guān)Java職責(zé)鏈模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Flowable執(zhí)行完畢的流程查找方法

    Flowable執(zhí)行完畢的流程查找方法

    這篇文章主要為大家介紹了Flowable執(zhí)行完畢的流程查找方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Java中轉(zhuǎn)換器設(shè)計模式深入講解

    Java中轉(zhuǎn)換器設(shè)計模式深入講解

    這篇文章主要給大家介紹了關(guān)于Java中轉(zhuǎn)換器設(shè)計模式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 使用MockMvc進行controller層單元測試 事務(wù)自動回滾的完整案例

    使用MockMvc進行controller層單元測試 事務(wù)自動回滾的完整案例

    這篇文章主要介紹了使用MockMvc進行controller層單元測試 事務(wù)自動回滾的完整案例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • JVM完全解讀之GC日志記錄分析

    JVM完全解讀之GC日志記錄分析

    這篇文章主要介紹了JVM完全解讀之GC日志記錄分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-01-01
  • Java中線程休眠編程實例

    Java中線程休眠編程實例

    這篇文章主要介紹了Java中線程休眠編程實例,本文直接給出代碼實例,并對休眠方法做了一番講解,需要的朋友可以參考下
    2015-06-06
  • Java中xxl-job實現(xiàn)分片廣播任務(wù)的示例

    Java中xxl-job實現(xiàn)分片廣播任務(wù)的示例

    本文主要介紹了Java中xxl-job實現(xiàn)分片廣播任務(wù)的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 基于springboot 長輪詢的實現(xiàn)操作

    基于springboot 長輪詢的實現(xiàn)操作

    這篇文章主要介紹了基于springboot 長輪詢的實現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • 帶你快速搞定java并發(fā)庫

    帶你快速搞定java并發(fā)庫

    本文主要介紹了java高并發(fā)寫入用戶信息到數(shù)據(jù)庫的幾種方法,具有很好的參考價值。下面跟著小編一起來看下吧,希望能給你帶來幫助
    2021-07-07
  • Springboot Mybatis-Plus數(shù)據(jù)庫單元測試實戰(zhàn)(三種方式)

    Springboot Mybatis-Plus數(shù)據(jù)庫單元測試實戰(zhàn)(三種方式)

    這篇文章主要介紹了Springboot Mybatis-Plus數(shù)據(jù)庫單元測試實戰(zhàn)(三種方式),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Spring?Boot?3中一套可以直接用于生產(chǎn)環(huán)境的Log4J2日志配置詳解

    Spring?Boot?3中一套可以直接用于生產(chǎn)環(huán)境的Log4J2日志配置詳解

    Log4J2是Apache Log4j的升級版,參考了logback的一些優(yōu)秀的設(shè)計,并且修復(fù)了一些問題,因此帶來了一些重大的提升,這篇文章主要介紹了Spring?Boot?3中一套可以直接用于生產(chǎn)環(huán)境的Log4J2日志配置,需要的朋友可以參考下
    2023-12-12

最新評論