Spring MVC:handlerAdapter

HandlerMapping这个组件,它负责的是定位请求处理器Handler。这是SpringMvc处理流程的第二步。那么,当定位到Handler之后,DispatcherServlet会将得到的Handler告知HandlerAdapter,HandlerAdapter再根据请求去定位请求的具体处理方法是哪一个。

职责

在HandlerMapping返回处理请求的Controller实例后,需要一个帮助定位具体请求方法的处理类,这个类就是HandlerAdapter,HandlerAdapter是处理器适配器,Spring MVC通过HandlerAdapter来实际调用处理函数。例如Spring MVC自动注册的AnnotationMethodHandlerAdpater,HandlerAdapter定义了如何处理请求的策略,通过请求url、请求Method和处理器的requestMapping定义,最终确定使用处理类的哪个方法来处理请求,并检查处理类相应处理方法的参数以及相关的Annotation配置,确定如何转换需要的参数传入调用方法,并最终调用返回ModelAndView。DispatcherServlet中根据HandlerMapping找到对应的handler method后,首先检查当前工程中注册的所有可用的handlerAdapter,根据handlerAdapter中的supports方法找到可以使用的handlerAdapter。通过调用handlerAdapter中的handler方法来处理及准备handler method的参数及annotation(这就是spring mvc如何将request中的参数变成handle method中的输入参数的地方),最终调用实际的handler method。

handlerAdapter接口

public abstract interface HandlerAdapter{
  public abstract boolean supports(Object paramObject);

  public abstract ModelAndView handle(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse, Object paramObject)
    throws Exception;

  public abstract long getLastModified(HttpServletRequest paramHttpServletRequest, Object paramObject);
}

该接口定义了三个方法,support方法的作用是判断处理适配器是不是支持该Handler。hanle方法,调用对应的Handler中适配到的方法,并返回一个ModelView。第三个方法不确定干嘛用的。

AnnotationMethodHandlerAdpater

supports方法实现

其中又调用了getMethodResolver这个方法后面又涉及到了很多东西,我看的不是很懂就不往更深的说了。它的主要逻辑是根据传入handler去取得ServletHandlerMethodResolver,这个ServletHandlerMethodResolver的作用可以简单的认为为解析能作为serlvet使用的方法。

public boolean supports(Object handler) {
        return getMethodResolver(handler).hasHandlerMethods();
    }
private ServletHandlerMethodResolver getMethodResolver(Object handler) {
    Class handlerClass = ClassUtils.getUserClass(handler);
    ServletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass);
    if (resolver == null) {
        resolver = new ServletHandlerMethodResolver(handlerClass);
        this.methodResolverCache.put(handlerClass, resolver);
    }
    return resolver;
}  

handle方法实现

public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {  

        if (AnnotationUtils.findAnnotation(handler.getClass(), SessionAttributes.class) != null) {
            // Always prevent caching in case of session attribute management.
            checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true);
            // Prepare cached set of session attributes names.
        }
        else {
            // Uses configured default cacheSeconds setting.
            checkAndPrepare(request, response, true);
        }  

        // Execute invokeHandlerMethod in synchronized block if required.
        if (this.synchronizeOnSession) {
            HttpSession session = request.getSession(false);
            if (session != null) {
                Object mutex = WebUtils.getSessionMutex(session);
                synchronized (mutex) {
                    return invokeHandlerMethod(request, response, handler);
                }
            }
        }  

        return invokeHandlerMethod(request, response, handler);
    } 

这个方法中的重点在于invokeHandlerMethod

protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {  

        ServletHandlerMethodResolver methodResolver = getMethodResolver(handler);
        Method handlerMethod = methodResolver.resolveHandlerMethod(request);
        ServletHandlerMethodInvoker methodInvoker = new ServletHandlerMethodInvoker(methodResolver);
        ServletWebRequest webRequest = new ServletWebRequest(request, response);
        ExtendedModelMap implicitModel = new BindingAwareModelMap();  

        Object result = methodInvoker.invokeHandlerMethod(handlerMethod, handler, webRequest, implicitModel);
        ModelAndView mav =
                methodInvoker.getModelAndView(handlerMethod, handler.getClass(), result, implicitModel, webRequest);
        methodInvoker.updateModelAttributes(handler, (mav != null ? mav.getModel() : null), implicitModel, webRequest);
        return mav;
    }  

其实它干的事情就是取得了handler中的对应请求的可执行方法,还是通过getMethodResolver方法实现的。在supports方法中已经构建了,所以这里调用的时候直接去缓存中取得就好了。
   小结:handlerAdapter这个类的作用就是接过handlermapping解析请求得到的handler对象。在更精确的定位到能够执行请求的方法。

参考:

http://blog.csdn.net/zhuojiajin/article/details/46597687

时间: 2024-12-23 11:21:26

Spring MVC:handlerAdapter的相关文章

Spring学习总结(2.3)-Spring MVC:handlerAdapter

前面一篇博客介绍了HandlerMapping这个组件,它负责的是定位请求处理器Handler.这是SpringMvc处理流程的第二步.那么,当定位到Handler之后,DispatcherServlet会将得到的Handler告知HandlerAdapter,HandlerAdapter再根据请求去定位请求的具体处理方法是哪一个. 职责 在HandlerMapping返回处理请求的Controller实例后,需要一个帮助定位具体请求方法的处理类,这个类就是HandlerAdapter,Hand

spring mvc 关键接口 HandlerMapping HandlerAdapter

HandlerMapping Spring mvc 使用HandlerMapping来找到并保存url请求和处理函数间的mapping关系.   以DefaultAnnotationHandlerMapping为例来具体看HandlerMapping的作用   DefaultAnnotationHandlerMapping将扫描当前所有已经注册的spring beans中的@requestmapping标注以找出url 和 handler method处理函数的关系并予以关联. Handlera

Spring MVC 学习笔记 handlerMapping和handlerAdapter

HandlerMapping Spring mvc 使用HandlerMapping来找到并保存url请求和处理函数间的mapping关系.   以DefaultAnnotationHandlerMapping为例来具体看HandlerMapping的作用   DefaultAnnotationHandlerMapping将扫描当前所有已经注册的spring beans中的@requestmapping标注以找出url 和 handler method处理函数的关系并予以关联. Handlera

Spring mvc之源码 handlerMapping和handlerAdapter分析

Spring mvc之源码 handlerMapping和handlerAdapter分析 本篇并不是具体分析Spring mvc,所以好多细节都是一笔带过,主要是带大家梳理一下整个Spring mvc的执行流程,以及如何根据URL查找处理器Controller的实现 (适合那些刚阅读源码不知道如何下手的人) http://www.guojinbao.com/borrow/borrowDetail/GETadLPjnf0[d].do 如何根据URL地址---->找到正确处理器Controller

Spring MVC 梳理 - handlerMapping和handlerAdapter分析

参考图片 综上所述我们来猜测一下spring mvc 中根据URL找到处理器Controller中相应方法的流程 ①:获取Request的URL ②:从UrlLookup这个map中找到相应的requestMappingInfo ③:如果没找到则遍历所有requestMappingInfo的信息直到找到匹配的requestMappingInfo ④:根据requestMappingInfo到mappingLookup中找到handlerMethod Spring mvc是如何通过URL查找到对应

spring mvc踩坑记

前言 主要介绍自己在学习spring mvc过程中踩到的一些坑,涉及到当时遇到这个错误是如何思考的,对思路进行总结,下次遇到类似的错误能够提供一些思路甚至快速解决. 环境准备 jdk8,spring4.3.3.RELEASE,spring mvc与spring版本一致,maven3.2.5,tomcat7 目标: 1.测试spring mvc的json参数绑定功能 2.测试spring mvc的返回json功能 项目目录(已经推送到github:https://github.com/Coming

spring MVC mybatis dispacherServlet(源码解读)

dispacherServlet是servlet的实现类,是spring MVC的前端转发器,是spring MVC的核心. 那么它做了哪些事呢? 它主要做了两件事: NO1: 看如下源码: /** * Initialize the strategy objects that this servlet uses. * <p>May be overridden in subclasses in order to initialize further strategy objects. */ pr

spring mvc学习 总体概览

spring mvc 设计概览 springmvc处理http请求,主要是在web.xml中配置一个dispatcherservlet,然后由此进行拦截并处理请求返回相应,下面就针对源码大体记录下dispatcherservlet的初始化和请求的处理流程. 具体的核心开发步骤: 1. DispatcherServlet在web.xml 中的部署描述,从而拦截请求到Spring Web MVC 2. HandlerMapping的配置,从而将请求映射到处理器,这里可以通过实现HandlerMapp

【转】Spring MVC 解读——&lt;mvc:annotation-driven/&gt;

转载自:http://my.oschina.net/HeliosFly/blog/205343 一.AnnotationDrivenBeanDefinitionParser 通常如果我们希望通过注解的方式来进行Spring MVC开发,我们都会在***-servlet.xml中加入<mvc:annotation-driven/>标签来告诉Spring我们的目的.但是我们为什么这么做呢?这个标签是什么意思呢?它做了什么呢? 同样为了弄清楚这些问题, 像<context:component-