DispatcherServlet 请求处理主逻辑 : 2. 选择 Handler 对应的 HandlerAdapter

该系列上一篇 : DispatcherServlet 请求处理主逻辑 : 1. 选择 Handler

本文代码版本 : spring-webmvc-5.1.5.RELEASE

DispatcherServlet请求处理主逻辑在找到能处理当前请求的handler之后,接下来就需要执行该Handler以处理请求了。那么,DispatcherServlet是直接执行该Handler吗?非也。这里Spring MVC引入了HandlerAdapter的概念。在Spring MVCHandlerAdapter是一个接口,该接口会被针对各种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了。不过,从该逻辑也可以看出,如果找不到能支持该HandlerHandlerAdapter,它会抛出异常ServletException声明这是一个配置错误。缺省情况下,框架对所有支持的Handler类型都提供了相应的HandlerAdapter支持,所以通常该异常分支并不会被执行到。但是如果开发人员提供了自定义的某种handler,但是又没有提供对应的HandlerAdapter支持,该异常分支就有可能被执行。

在这里,你可能会问另外一个问题,属性this.handlerAdapters内的信息又是从哪里来的呢?其实,这些信息是在DispatcherServlet初始化过程中进行的,具体可以参考 : Spring MVC DispatcherServlet 策略初始化 – initHandlerAdapters

Spring MVC框架在配置过程中提供了多种HandlerAdapter以支持不同的Handler类型,具体可以参考:

  1. Spring MVC : WebMvcConfigurationSupport 中定义的 HandlerAdapter 组件
  2. Spring MVC : 框架提供的 HandlerAdapter 实现

总结

本文梳理了DispatcherServlet根据Handler之后获取相应的HandlerAdapter的过程,包含如下要点 :

  • HandlerAdapter是什么 ?
  • 这些HandlerAdapter从哪里来 ?
  • 如何判断一个HandlerAdapter是否支持某个Handler ?
  • 已经有了Handler,为什么还要使用HandlerAdapter ?
  • 如果找不到HandlerHandlerAdapter会怎么样 ?
  • 有哪些类型的HandlerAdapter?

相关文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值