设计模式之责任链模式(附:spring mvc中HandlerExecutionChain源码应用分析)

一、概述

1、定义

        Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.(使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。)

2、通用类图

设计模式之责任链模式(附:spring mvc中HandlerExecutionChain源码应用分析)_第1张图片

3、基本介绍
  • 责任链模式为请求创建了一个接收者对象的链,这种模式对请求的发送者和接收者进行解耦。

  • 在责任链模式中,通常每个接收者都包含对另一个接受者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者。

二、通用源码

处理者角色:
        处理者实现3个职责:①定义一个请求的处理方法handleMessage,唯一对外开放的方法;②定义一个链的编排方法setNext,设置下一个处理者;③定义具体的请求者必须实现的两个方法,即自己能够处理的级别getHandlerLevel和具体的处理任务echo。

//抽象处理者
public abstract class Handler {
     
    private Handler nextHandler;
    
    //每个处理者都必须对请求做出处理
    public final Response handleMessage(Request request){
     
        Response response=null;
        //判断是否是自己的处理级别
        if (this.getHandlerLevel().equals(request.getRequestLevel())){
     
            response=this.echo(request);
        }else {
     //不属于自己的处理级别
            //判断是否有下一个处理者
            if (this.nextHandler!=null){
     
                response=this.nextHandler.handleMessage(request);
            }else {
     
                //没有适当的处理者,则业务自行处理
                System.out.println("没有适当的处理者");
            }
        }
        return response;
    }
    
    //设置下一个处理者是谁
    public void setNextHandler(Handler nextHandler){
     
        this.nextHandler=nextHandler;
    }
    
    //每个处理者都有一个处理级别
    protected abstract Level getHandlerLevel();
    
    //每个处理者都必须实现处理业务
    protected abstract Response echo(Request request);
}

//具体的处理者1
public class ConcreteHandler1 extends Handler {
     
    
    //设置自己的处理级别
    @Override
    protected Level getHandlerLevel() {
     
        return null;
    }
    
    //完成自己的逻辑处理
    @Override
    protected Response echo(Request request) {
     
        return null;
    }
}

//具体的处理者2
public class ConcreteHandler2  extends Handler{
     

    //设置自己的处理级别
    @Override
    protected Level getHandlerLevel() {
     
        return null;
    }

    //完成自己的逻辑处理
    @Override
    protected Response echo(Request request) {
     
        return null;
    }
}

Client端调用:

public class Client {
     
    
    public static void main(String[] args){
     
        //声明所有的处理节点
        Handler handler1=new ConcreteHandler1();
        Handler handler2=new ConcreteHandler2();
        //设置链中的执行顺序
        handler1.setNextHandler(handler2);
        //当然,还可以添加很多处理者,
        //提交请求,返回结果
        Response response=handler1.handleMessage(new Request());
    }
}

其它用到的辅助类:

public class Level {
     
    //定义一个请求和处理等级
}

public class Request {
     

    //请求的等级
    public Level getRequestLevel(){
     
        return null;
    }
}

public class Response {
     
    //处理者返回的数据
}

三、责任链模式的应用

1、优点
  • 将请求和处理分开,请求者不用知道是谁处理的,处理者不用知道请求的全貌,实现了两者之间的解耦。
2、缺点
  • 性能问题,每个请求都是从链头遍历到链尾,特别是当链比较长的时候,性能是一个非常大的问题;
  • 不易测试,链条比较长时,给程序的调试增加了难度。
3、注意事项
  • 链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经超过其阈值,超过则不允许建立,避免无意识的破环系统性能。

四、HandlerExecutionChain中责任链模式应用分析

1、类图分析

        HandlerExecutionChain是一个责任链,其中的方法applyPreHandler(),applyPostHandle()和triggerAfterCompletion()相当于具体的处理类。在DispatcherServlet类的doDispatch()方法中进行条件判断实现处理的传递。
设计模式之责任链模式(附:spring mvc中HandlerExecutionChain源码应用分析)_第2张图片

2、部分源码

DispatcherServlet类:

public class DispatcherServlet extends FrameworkServlet {
     

	//实现责任的传递处理
	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
     
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

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

			try {
     
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

				// Determine handler for the current request.
				//获取责任链
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null || mappedHandler.getHandler() == null) {
     
					noHandlerFound(processedRequest, response);
					return;
				}

				// Determine handler adapter for the current request.
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

				// Process last-modified header, if supported by the handler.
				String method = request.getMethod();
				boolean isGet = "GET".equals(method);
				if (isGet || "HEAD".equals(method)) {
     
					long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
					if (logger.isDebugEnabled()) {
     
						logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
					}
					if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
     
						return;
					}
				}
				//交给applyPreHandle进行处理,
				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
     
					return;
				}

				// Actually invoke the handler.
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

				if (asyncManager.isConcurrentHandlingStarted()) {
     
					return;
				}

				applyDefaultViewName(processedRequest, mv);
				//交给applyPostHandle处理
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}
			catch (Exception ex) {
     
				dispatchException = ex;
			}
			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
		catch (Exception ex) {
     
			triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
		}
		catch (Error err) {
     
			triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
		}
		finally {
     
			if (asyncManager.isConcurrentHandlingStarted()) {
     
				// Instead of postHandle and afterCompletion
				if (mappedHandler != null) {
     
					mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
				}
			}
			else {
     
				// Clean up any resources used by a multipart request.
				if (multipartRequestParsed) {
     
					cleanupMultipart(processedRequest);
				}
			}
		}
	}

}

HandlerExecutionChain:

public class HandlerExecutionChain {
     
	
	/**
	 * Apply preHandle methods of registered interceptors.
	 * @return {@code true} if the execution chain should proceed with the
	 * next interceptor or the handler itself. Else, DispatcherServlet assumes
	 * that this interceptor has already dealt with the response itself.
	 */
	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;
	}
}

	/**
	 * Apply postHandle methods of registered interceptors.
	 */
	void applyPostHandle(HttpServletRequest request, HttpServletResponse response, 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);
			}
		}
	}


	/**
	 * Trigger afterCompletion callbacks on the mapped HandlerInterceptors.
	 * Will just invoke afterCompletion for all interceptors whose preHandle invocation
	 * has successfully completed and returned true.
	 */
	void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, 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);
				}
			}
		}
	}

你可能感兴趣的:(设计模式)