- HandlerAdapter用于调用处理器方法,并且为处理器方法提供参数解析、返回值处理等适配工作,使使用者专心于业务逻辑的实现。
- 几种HandlerAdapter都实现了HandlerAdapter接口,接口中声明了三种重要的方法:
1. supports方法用于判断该HandlerAdapter是否支持指定处理器,支持则可调用;
2. handle方法调用处理器;
3. getLastModified判断是否是最后修改。
- 几种HandlerAdapter对上述三种方法的实现各有或大或小的不同,因而其功能耶各有所不同。
下面详细介绍这几种HandlerAdapter:
AnnotationMethodHandlerAdapter
注解方法处理器适配器
这个类的实现是基于注解的实现,它需要结合注解方法映射和注解方法处理器协同工作。它通过解析声明在注解控制器的请求映射信息来解析相应的处理器方法来处理当前的HTTP请求。在处理的过程中,它通过反射来发现探测处理器方法的参数,调用处理器方法,并且映射返回值到模型和控制器对象,最后返回模型和控制器对象给作为主控制器的派遣器Servlet。
supports(Object handler):
判断是否有匹配的处理器
handle():
handle()调用AnnotationMethodHandlerAdapter的invokeHandlerMethod(r,r,h)方法完成1.入参处理2.handler调用3.返回值处理。AnnotationMethodHandlerAdapter包含多个内部类,其中内部类ServletHandlerMethodInvoker继承于HandlerMethodInvoker,invokeHandlerMethod(r,r,h)内部实例化ServletHandlerMethodInvoker内部类,并调用其父类HandlerMethodInvoker的invokeHandlerMethod(...)方法,实现上述三个任务。invokeHandlerMethod(...)方法有两个关键步骤,一个是resolveHandlerArguments(...)通过识别各注解,解析注解并获取注解修饰的参数值到Object [] args数组中返回;另一个是调用了Method类的Object invoke(Object obj,Object... args)方法,调用handler执行处理器方法,返回的Object对象result。此后,invokeHandlerMethod(r,r,h)方法中继续执行AnnotationMethodHandlerAdapter的内部类ServletHandlerMethodInvoker的getModelAndView(...)获取ModelAndView,以及内部类ServletHandlerMethodInvoker的父类HandlerMethodInvoker的updateModelAttributes(...)方法更新Model数据,然后返回ModelAndView,invokeHandlerMethod(r,r,h)执行结束,handle()执行结束。
getLastModified(r,h):
返回-1。HTTP响应消息头有一个Last-Modified字段,这个字段表示服务器内容最新修改时间。根据这个方法的返回值来决定是否要调用doGet方法和生成Last-Modified头字段。当getLastModified返回-1时,service方法总会调用doGet方法。(简写 r:request r:response h:handler)
handle方法关键步骤:
RequestMappingHandlerAdapter
请求映射处理器适配器
RequestMappingHandlerAdapter继承于AbstractHandlerMethodAdapter,AbstractHandlerMethodAdapter中有非抽象方法supports(Object)、handle(HttpServletRequest,HttpServletResponse,Object)、getLastModified(HttpServletRequest,Object),RequestMappingHandlerAdapter直接继承这三个方法,不再重写。RequestMappingHandlerAdapter实现AbstractHandlerMethodAdapter中的抽象方法supportsInternal(HandlerMethod)、handleInternal(HttpServletRequest,HttpServletResponse,HandlerMethod)、getLastModifiedInternal(HttpServletRequest,HandlerMethod)。
RequestMappingHandlerAdapter的消息转换机制请参考我的另一篇文章:RequestMappingHandlerAdapter消息转换机制
supports(Object):
要求handler是HandlerMethod的实例,并且supportsInternal方法返回true。用于判断是否有匹配的处理器。
handle(HttpServletRequest,HttpServletResponse,Object):
直接调用handleInternal(HttpServletRequest,HttpServletResponse,HandlerMethod)方法。调用处理器。
getLastModified(HttpServletRequest,Object):
直接调用getLastModifiedInternal(HttpServletRequest,HandlerMethod)方法。
</br>
supportsInternal(HandlerMethod):
返回true,判断是否有匹配的处理器
</br>
handleInternal(r,r,handler method)
调用RequestMappingHandlerAdapter类的invokeHandleMethod(r,r,handler method)方法执行1.入参处理2.handler调用3.返回值处理。RequestMappingHandlerAdapter在进行handle的时候,会委托给HandlerMethod(具体由子类ServletInvocableHandlerMethod处理)的invokeAndHandle方法进行处理,这个方法将返回值处理转接给HandlerMethodReturnValueHandlerComposite处理。HandlerMethodReturnValueHandlerComposite维护了一个HandlerMethodReturnValueHandler列表。HandlerMethodReturnValueHandlerComposite是一个对返回值进行处理的策略接口,HandlerMethodArgumentComposite类似。
</br>
getLastModifiedInternal(r,h):
返回-1。service方法总会调用doGet方法。
HttpRequestHandlerAdapter
HTTP请求处理器适配器
HTTP请求处理器适配器仅仅支持对HTTP请求处理器的适配。它简单的将HTTP请求对象和响应对象传递给HTTP请求处理器的实现,它并不需要返回值。它主要应用在基于HTTP的远程调用的实现上。
转发request和response
supports(Object handler):
要求handler处理器实现了HttpRequestHandler接口
handle(r,r,handler method)
特点:直接返回null的ModelAndView。调用void handleRequest(r,r),获取RequestDispatcher,若其不为null,则转发request和response。
getLastModified(r,h):
如果handler实现了LastModified接口,可反射调用lastModified方法,然后返回-1;否则直接返回-1。
SimpleServletHandlerAdapter
简单Servlet处理器适配器
这个实现能够将一个HTTP请求传递给一个Servlet规范中定义的Servlet的实现进行处理。它的应用并不广泛,主要应用在适配到一个已有的Servlet的实现以达到重用的目的。基于简单控制器流程的实现中,有个相似的类ServletWrappingController实现了同样的业务逻辑。
supports(Object handler):
要求handler处理器实现了Servlet接口
handle(r,r,h)
特点:直接返回null的ModelAndView。调用Servlet的void service(r,r),Servlet直接处理请求。
getLastModified(r,h):
直接返回-1。
SimpleControllerHandlerAdapter
简单控制器处理器适配器
这个实现类将HTTP请求适配到一个控制器的实现进行处理。这里控制器的实现是一个简单的控制器接口的实现。简单控制器处理器适配器被设计成一个框架类的实现,不需要被改写,客户化的业务逻辑通常是在控制器接口的实现类中实现的。
supports(Object handler):
要求handler处理器实现了Controller接口
handle(r,r,h):
特点:调用AbstractController的ModelAndView handleRequest(r,r)方法,返回ModelAndView。
getLastModified(r,h):
如果handler实现了LastModified接口,可反射调用lastModified方法,然后返回-1;否则直接返回-1。
参考文献:
参数解析、返回值处理看过的写的最好的文章——SpringMVC中Controller
几种handlerAdapter的简介——深入剖析Spring Web源码(十二) - 处理器映射,处理器适配器以及处理器的实现 - 处理器适配器的实现架构
看看——SpringMVC源码总结(一)HandlerMapping和HandlerAdapter入门
请求处理的时序图——Spring MVC源码分析(续)——请求处理
看看——Spring MVC之DispatcherServlet初始化