该模式避免了请求与多个处理者之间的耦合。说直白点,就是从多个处理者中选择一个,我们平时的想法是if else判断,但当处理者过多的时候就过于复杂,且增加或删除处理者,会改变业务代码,不满足开闭原则。
从结构图可以看出,我们对处理者与处理者之间指定了顺序,如果该处理者处理不了就交给下一个。当处理者之间的顺序不要求的时候也可以直接用集合代替。
下面以SpringMVC中的doDispatch方法中,getHandlerAdapter方法对职责链进行分析。
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());
下面见上述流程简述一下:
MVC根据外部请求取到合适的handler,再通过handler寻找合适的adapter,那怎么寻找呢?这里用到了职责链模式
定义HandlerAdapter接口:
public interface HandlerAdapter {
//是否支持该handler
boolean supports(Object handler);
//请求处理
void handler();
}
具体的适配器实现HandlerAdapter接口:
public class AnnotationMethodHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof AnnotationMethodHandler);
}
@Override
public void handler() {
System.out.println("请求交给AnnotationMethodHandlerAdapter处理");
}
}
public class RequestMappingHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof RequestMappingHandler);
}
@Override
public void handler() {
System.out.println("请求交给RequestMappingHandlerAdapter处理");
}
}
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof SimpleControllerHandler);
}
@Override
public void handler() {
System.out.println("请求交给SimpleControllerHandlerAdapter处理");
}
}
用户使用时:
public class Main {
public static void main(String[] args) {
//前期预处理,假设链上有这三种adapter
List handlerAdapterList = new ArrayList<>();
handlerAdapterList.add(new RequestMappingHandlerAdapter());
handlerAdapterList.add(new SimpleControllerHandlerAdapter());
handlerAdapterList.add(new AnnotationMethodHandlerAdapter());
//假如请求的handler为RequestMappingHandler
RequestMappingHandler handler = new RequestMappingHandler();
//根据职责链匹配查找,这里没有指定职责链的顺序,也是可以的
for (HandlerAdapter ha : handlerAdapterList) {
if (ha.supports(handler)) {
ha.handler();
}
}
}
}
这样,当RequestMappingHandler时,会找到合适的适配器,并交给它处理了。当增加适配器的时候,只要增加处理类,不需要修改业务代码。
for (HandlerAdapter ha : handlerAdapterList) {
if (ha.supports(handler)) {
ha.handler();
}
}