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.(使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。)
责任链模式为请求创建了一个接收者对象的链,这种模式对请求的发送者和接收者进行解耦。
在责任链模式中,通常每个接收者都包含对另一个接受者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者。
处理者角色:
处理者实现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 {
//处理者返回的数据
}
HandlerExecutionChain是一个责任链,其中的方法applyPreHandler(),applyPostHandle()和triggerAfterCompletion()相当于具体的处理类。在DispatcherServlet类的doDispatch()方法中进行条件判断实现处理的传递。
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);
}
}
}
}