一、什么是HandlerAdapter

Note that a handler can be of type Object. This is to enable handlers from other frameworks to be integrated with this framework without custom coding.

boolean supports(Object handler)

Given a handler instance, return whether or not this HandlerAdapter can support it.

HandlerAdapter 接口实现类:

1. HttpRequestHandlerAdapter : 要求handler实现HttpRequestHandler接口

public class HttpRequestHandlerAdapter implements HandlerAdapter {

    @Override
public boolean supports(Object handler) {
return (handler instanceof HttpRequestHandler);
} @Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response);
return null;
} @Override
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
} }

2. SimpleControllerHandlerAdapter:要求handler实现Controller接口,该接口的方法参数为ModelAndView

public class SimpleControllerHandlerAdapter implements HandlerAdapter {

    @Override
public boolean supports(Object handler) {
return (handler instanceof Controller);
} @Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception { return ((Controller) handler).handleRequest(request, response);
} @Override
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
} }

3. AbstracthandlerMethodAdapter的handle()使用模板方法,调用子类handleInternal()实现

    @Override
public final boolean supports(Object handler) {
return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
} protected abstract boolean supportsInternal(HandlerMethod handlerMethod); @Override
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception { return handleInternal(request, response, (HandlerMethod) handler);
} protected abstract ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception;

AbstracthandlerMethodAdapter及其子类RequestMappingHandlerAdapter的supportsInternal()方法

    /**
* Always return {@code true} since any method argument and return value
* type will be processed in some way. A method argument not recognized
* by any HandlerMethodArgumentResolver is interpreted as a request parameter
* if it is a simple type, or as a model attribute otherwise. A return value
* not recognized by any HandlerMethodReturnValueHandler will be interpreted
* as a model attribute.
*/
@Override
protected boolean supportsInternal(HandlerMethod handlerMethod) {
return true;
}

二、什么是HandlerMethod:封装了请求处理方法的参数和返回值,及该方法上的注解

Encapsulates information about a handler method consisting of a method and a bean. Provides convenient access to method parameters, the method return value, method annotations, etc.

The class may be created with a bean instance or with a bean name (e.g. lazy-init bean, prototype bean).

Use createWithResolvedBean() to obtain a HandlerMethod instance with a bean instance resolved through the associated BeanFactory.

三、什么时候使用HandlerAdapter

1. DispatchServlet protected void doDispatch()方法会获取相应的HandlerAdapter

                // Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

在以前的文章中,已经说过RequestMappingHandlerAdapter是处理输入输出的关键点,也是spring根据相应的路径查找对应的处理器的关键点

RequestMappingHandlerAdapter的handleInternal()会调用invokeHandlerMethod()

    protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
        //创建ServletInvocableHandlerMethod
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
invocableMethod.setDataBinderFactory(binderFactory);
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer); ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect); AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
asyncWebRequest.setTimeout(this.asyncRequestTimeout); WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.setTaskExecutor(this.taskExecutor);
asyncManager.setAsyncWebRequest(asyncWebRequest);
asyncManager.registerCallableInterceptors(this.callableInterceptors);
asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors); if (asyncManager.hasConcurrentResult()) {
Object result = asyncManager.getConcurrentResult();
mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
asyncManager.clearConcurrentResult();
if (logger.isDebugEnabled()) {
logger.debug("Found concurrent result value [" + result + "]");
}
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
//调用
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
} return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
}

3.一个请求过来时,InvocableHandlerMethod的执行变量

从上面的分析看到,处理请求时,会调用invokeAndHandle(),最终是doInvoke执行

4.  疑问:这些HandlerMethond是什么时候载入系统的

解答:系统启动的时候执行registerHandlerMethod()方法,创建HandlerMethod实例

三、HandlerMapping VS HandlerAdapter

The strategy interface HandlerAdapter takes the role of invoking handler methods selected by some HandlerMapping.

SpringMVC(四):什么是HandlerAdapter的更多相关文章

  1. SpringMVC源码解析- HandlerAdapter - ModelFactory(转)

    ModelFactory主要是两个职责: 1. 初始化model 2. 处理器执行后将modle中相应参数设置到SessionAttributes中 我们来看看具体的处理逻辑(直接充当分析目录): 1 ...

  2. SpringMVC源码解析- HandlerAdapter - ModelFactory

    ModelFactory主要是两个职责: 1. 初始化model 2. 处理器执行后将modle中相应参数设置到SessionAttributes中 我们来看看具体的处理逻辑(直接充当分析目录): 1 ...

  3. springMVC源码分析--HandlerAdapter(一)

    HandlerAdapter的功能实际就是执行我们的具体的Controller.Servlet或者HttpRequestHandler中的方法. 类结构如下:

  4. Spring MVC源码分析(三):SpringMVC的HandlerMapping和HandlerAdapter的体系结构设计与实现

    概述在我的上一篇文章:Spring源码分析(三):DispatcherServlet的设计与实现中提到,DispatcherServlet在接收到客户端请求时,会遍历DispatcherServlet ...

  5. springmvc(四) springmvc的数据校验的实现

    so easy~ --WH 一.什么是数据校验? 这个比较好理解,就是用来验证客户输入的数据是否合法,比如客户登录时,用户名不能为空,或者不能超出指定长度等要求,这就叫做数据校验. 数据校验分为客户端 ...

  6. SpringMVC(四):@RequestMapping结合org.springframework.web.filter.HiddenHttpMethodFilter实现REST请求

    1)REST具体表现: --- /account/1  HTTP GET       获取id=1的account --- /account/1  HTTP DELETE 删除id=1的account ...

  7. SpringMVC(四) RequestMapping请求方式

    常见的Rest API的Get和POST的测试参考代码如下,其中web.xml和Springmvc的配置文件参考HelloWorld测试代码中的配置. 控制类的代码如下: package com.ti ...

  8. SSM-SpringMVC-17:SpringMVC中深度剖析HandlerAdapter处理器适配器底层

     ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 先放一张图 很熟悉啊,之前就看过,我们之前已经把handlerMapping剖了个底朝天,顺着上次的进度,继 ...

  9. SpringMVC源码解析 - HandlerAdapter - @SessionAttributes注解处理

    使用SpringMVC开发时,可以使用@SessionAttributes注解缓存信息.这样业务开发时,就不需要一次次手动操作session保存,读数据. @Controller @RequestMa ...

随机推荐

  1. Android 开发笔记

    11.android使用全局变量 定义Data类继承Application 在manifest.xml中声明 http://blog.csdn.net/feiyangxiaomi/article/de ...

  2. webview调起浏览器

    调起浏览器 url = "intent://" + url +"#Intent;scheme=http;action=android.intent.action.VIEW ...

  3. 【OpenFOAM案例】01 elbow

    本案例演示利用OpenFOAM的icoFoam求解器计算弯曲管道中的混合流动问题. 1 拷贝tutorials文件 启动终端,且拷贝tutorials文件夹中的文件.利用命令: cp -r $FOAM ...

  4. Quartz与Spring Boot集成使用

    上次自己搭建Quartz已经是几年前的事了,这次项目中需要定时任务,需要支持集群部署,想到比较轻量级的定时任务框架就是Quartz,于是来一波. 版本说明 通过搜索引擎很容易找到其官网,来到Docum ...

  5. 【Log】SLF4J简单入门

    SLF4J介绍 SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统.按照官方的说法,SLF4J是一个用于日 ...

  6. eclipse is missing required source folder src/test/java

    原因:maven的bug,不兼容eclipse 解决方法:右击工程,选择run-->maven-->build重新构建工程,就解决了.

  7. [转]Mybatis foreach 批量操作

    原文地址:https://blog.csdn.net/jason5186/article/details/40896043 foreach属性属性    描述item    循环体中的具体对象.支持属 ...

  8. 如何查看.Net Framework版本

    地址栏输入 %systemroot%\Microsoft.NET\Framework,或win+R快捷方式打开“运行”窗口,输入%systemroot%\Microsoft.NET\Framework ...

  9. java生成兑换码礼包码--工具类

    import java.util.HashSet; import java.util.Random; import java.util.Set; public class GenSerial { pr ...

  10. 【javascript】定时器组件

    'use strict'; module.exports = function() { this.timer = {}; this.config = {}; // 初始化参数 this.init = ...