本文代码版本 : spring-webmvc-5.1.5.RELEASE
DispatcherServlet
请求处理主逻辑在找到能处理当前请求的handler
之后,接下来就需要执行该Handler
以处理请求了。那么,DispatcherServlet
是直接执行该Handler
吗?非也。这里Spring MVC
引入了HandlerAdapter
的概念。在Spring MVC
中HandlerAdapter
是一个接口,该接口会被针对各种Handler
类型实现以处理各种请求。实际上,DispatcherServlet
请求处理过程中,执行Handler
处理请求是通过HandlerAdapter
完成的,而并非是DispatcherServlet
直接调用Handler
提供的处理方法。
那么为什么要有一层HandlerAdapter
呢?这是为了使DispatcherServlet
具备更强的扩展性,并隔离DispatcherServlet
的请求处理主流程逻辑和具体的handler
调用细节。当要支持更多的Handler
类型时,可以实现相应的HandlerAdapter
隐藏具体的Handler
调用细节,而DispatcherServlet
只需要找到相应的Handler
类型的HandlerAdapter
使用统一的方式就可以完成对请求的处理,从而以不变应万变。
接下来我们看DispatcherServlet
请求处理主流程根据handler
获取相应的HandlerAdapter
的调用语句:
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
此处可见,获得相应HandlerAdapter
的逻辑是由getHandlerAdapter
方法提供的。源代码如下所示 :
/**
* Return the HandlerAdapter for this handler object.
* @param handler the handler object to find an adapter for
* @throws ServletException if no HandlerAdapter can be found for the handler.
* This is a fatal error.
*/
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
getHandlerAdapter
方法实现并无难懂之处。主要就是在属性this.handlerAdapters
不为null
时遍历其中保存的每个HandlerAdapter
,看它能不能支持给定Handler
。而能不能支持某种Handler
,是由HandlerAdapter
实现类自己决定的。这里如果被遍历到的HandlerAdapter
支持参数Handler
的话,getHandlerAdapter
方法就返回相应的HandlerAdapter
,这也就是最终要应用于执行Handler
处理当前请求的HandlerAdapter
了。不过,从该逻辑也可以看出,如果找不到能支持该Handler
的HandlerAdapter
,它会抛出异常ServletException
声明这是一个配置错误。缺省情况下,框架对所有支持的Handler
类型都提供了相应的HandlerAdapter
支持,所以通常该异常分支并不会被执行到。但是如果开发人员提供了自定义的某种handler
,但是又没有提供对应的HandlerAdapter
支持,该异常分支就有可能被执行。
在这里,你可能会问另外一个问题,属性this.handlerAdapters
内的信息又是从哪里来的呢?其实,这些信息是在DispatcherServlet
初始化过程中进行的,具体可以参考 : Spring MVC DispatcherServlet 策略初始化 – initHandlerAdapters
Spring MVC
框架在配置过程中提供了多种HandlerAdapter
以支持不同的Handler
类型,具体可以参考:
总结
本文梳理了DispatcherServlet
根据Handler
之后获取相应的HandlerAdapter
的过程,包含如下要点 :
HandlerAdapter
是什么 ?- 这些
HandlerAdapter
从哪里来 ? - 如何判断一个
HandlerAdapter
是否支持某个Handler
? - 已经有了
Handler
,为什么还要使用HandlerAdapter
? - 如果找不到
Handler
的HandlerAdapter
会怎么样 ? - 有哪些类型的
HandlerAdapter
?