实现Controller的三种方式分析

每种实现的方式对应的HanderAdapter都不同。

实现Controller接口

该接口对应的HanderAdapter为SimpleControllerHandlerAdapter。

使用案列:

 public class LeController implements Controller {

	 @Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 创建数据视图类
ModelAndView mv = new ModelAndView();
// 填充数据
mv.addObject("msg","北方情韵");
// 跳转的视图
mv.setViewName("index");
return mv;
}
}

配置对应的bean信息,这里的name就是访问该Controller的路径。

<bean class="cn.lele.controller.LeController" name="/le" />

我们可以通过debug那个执行链就可以知道。

实现HttpRequestHandler接口

该接口对应的HanderAdapter为HttpRequestHandlerAdapter。

使用案例:

 public class YueController implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("msg","实现接口HttpRequestHandler");
request.getRequestDispatcher("/WEB-INF/pages/index.jsp").forward(request,response);
} }

配置对应的bean信息,这里的name就是访问该Controller的路径。

<bean class="cn.lele.controller.YueController" name="/yue" />

继续查看当前对象的执行链:

这两种方式大体上是类似的,我们可以区别的看一下,他们是怎么处理的。

先看实现HttpRequestHandlerAdapter接口的:

进入1075行代码:

可以发现,这是把当前Controller强转为HttpRequestHander,然后再执行HttpRequestHanderAdapter的handleRequest方法。(实际就是去执行我们Controller里面的方法。)

而HttpRequestHandler正是我们Contoller类实现的HttpRequestHandler。

同理,我们去看一下实现Controller接口的类的处理方法。

一样,都是先强转为接口类,然后执行对应的方法,也就是我们自己实现的方法:

注意:当前的所处位置:

使用注解的方式

待补充

探究HandlerAdapter的装配规则

一直都很疑惑:

为什么不装配全部都能用,只装配一种,不符合的就不能用了呢?

未配置HandlerAdapter

观察DispatcherServlet的初始化方法:

可以看到有对HandlerAdapter的初始化,点进去加断点。

开始Debug:

根据注释,我们可以知道如果此时HandlerAdapters如果为空的话将加载初始化的HandlerAdapters

可以看到,在664行加载了四个HandlerAdapter

进入此方法继续debug查看:

注意:DispatcherServlet的初始化方法只执行一次,后面需要重新启动tomcat才能继续进入初始化方法。

重启后,继续Debug:

往下走,可以看到这里读取到了几个HandlerAdapter

很明显872行代码是读取了什么文件

重新Debug可以发现这里读取的是org/springframework/web/servlet/DispatcherServlet.properties文件。

DispatcherServlet.properties:

......

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
org.springframework.web.servlet.function.support.HandlerFunctionAdapter ......

文件里内容不少,我这里只留下了HandlerAdapter的信息了

继续往下看怎么处理的:

下面我感觉应该是利用泛型和反射得到所有的处理器。

配置了HandlerAdapter

如果我们再容器中装配了Adapter:

重启tomcat,继续Debug

可以看到642行读取到了我们配置的两个HandlerAdapter,并且再645行赋值给了DispatcherServlet的handlerAdapters,此时方法就会结束了。因为下面都不符合条件了。

总结:

如果我们在容器里添加了HandlerAdapter,那么就不会通过读取本地的文件添加默认的四个HandlerAdapter。

如果没在容器中添加HandlerAdapter,机会读取本地的DispatcherServlet.properties里面的四个HandlerAdapter。

SpringMVC基础源码分析(一)的更多相关文章

  1. SpringBoot中Tomcat和SpringMVC整合源码分析

    概述 ​ SpringBoot中集成官方的第三方组件是通过在POM文件中添加组件的starter的Maven依赖来完成的.添加相关的Maven依赖之后,会引入具体的jar包,在SpringBoot启动 ...

  2. SpringMVC源码分析系列

    说到java的mvc框架,struts2和springmvc想必大家都知道,struts2的设计基本上完全脱离了Servlet容器,而springmvc是依托着Servlet容器元素来设计的,同时sp ...

  3. Spring源码分析专题——目录

    Spring源码分析专题 -- 阅读指引 IOC容器 Spring源码分析专题 -- IOC容器启动过程(上篇) Spring源码分析专题 -- IOC容器启动过程(中篇) Spring源码分析专题 ...

  4. SpringMVC拦截器详解[附带源码分析]

    目录 前言 重要接口及类介绍 源码分析 拦截器的配置 编写自定义的拦截器 总结 总结 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:h ...

  5. SpringMVC视图机制详解[附带源码分析]

    目录 前言 重要接口和类介绍 源码分析 编码自定义的ViewResolver 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门bl ...

  6. 详解SpringMVC请求的时候是如何找到正确的Controller[附带源码分析]

    目录 前言 源码分析 重要接口介绍 SpringMVC初始化的时候做了什么 HandlerExecutionChain的获取 实例 资源文件映射 总结 参考资料 前言 SpringMVC是目前主流的W ...

  7. SpringMVC类型转换、数据绑定详解[附带源码分析]

    目录 前言 属性编辑器介绍 重要接口和类介绍 部分类和接口测试 源码分析 编写自定义的属性编辑器 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那 ...

  8. [转]SpringMVC拦截器详解[附带源码分析]

      目录 前言 重要接口及类介绍 源码分析 拦截器的配置 编写自定义的拦截器 总结 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:ht ...

  9. springMVC容器加载源码分析

    springmvc是一个基于servlet容器的轻量灵活的mvc框架,在它整个请求过程中,为了能够灵活定制各种需求,所以提供了一系列的组件完成整个请求的映射,响应等等处理.这里我们来分析下spring ...

  10. SpringMVC拦截器详解[附带源码分析](转)

    本文转自http://www.cnblogs.com/fangjian0423/p/springMVC-interceptor.html 感谢作者 目录 前言 重要接口及类介绍 源码分析 拦截器的配置 ...

随机推荐

  1. live-player live-pusher惨案

    昨天遇到的问题,旧项目: 一个页面同时使用live-player和live-pusher时候遇到的问题,live-pusher正常,live-player无效,没有任何报错 打log 所有livepl ...

  2. Flutter和Rust如何优雅的交互

    前言 文章的图片链接都是在github上,可能需要...你懂得:本文含有大量关键步骤配置图片,强烈建议在合适环境下阅读 Flutter直接调用C层还是蛮有魅力,想想你练习C++,然后直接能用flutt ...

  3. BeanShell 后置处理器/前置处理器实现urldecode 解码

    1.使用正则/Json提取器提取需要解码的值 2.在提取的接口中添加后置处理器或在下个调用接口中添加前置处理器 3.编码实现 String token = vars.get("access_ ...

  4. 彻底弄懂Javascript模块导入导出

    笔者开始学习Javascript的时候,对模块不太懂,不知道怎么导入模块,导出模块,就胡乱一通试 比如 import xx from 'test.js' 不起作用,就加个括号 import {xx} ...

  5. [OpenCV实战]20 使用OpenCV实现基于增强相关系数最大化的图像对齐

    目录 1 背景 1.1 彩色摄影的一个简短而不完整的历史 1.2 OpenCV中的运动模型 2 使用增强相关系数最大化(ECC)的图像对齐 2.1 findTransformECC在OpenCV中的示 ...

  6. NSOperation的简单使用

    1.默认情况下,NSOperation并不具备封装操作的能力,必须使用它的子类,使用NSOperation子类的方式有3种: 1> NSInvocationOperation 2> NSB ...

  7. 洛谷P1259 黑白棋子的移动 题解

    本蒟蒻这题用的打表做法,其实也可以理解为是一种递推. 先来观察一下样例: 当n为7时,输出共有14行,易得输出行数为2n. ooooooo*******-- oooooo--******o* oooo ...

  8. centos7系统的安装部署过程

    一.进入系统引导界面进行配置 引导项说明: 安装centos7系统(*) 测试光盘镜像并安装系统 排错模式(修复系统 重置系统密码) 补充:centos7系统网卡名称 默认系统的网卡名称 eth0 e ...

  9. 五种传统IO模型

    五种传统I/O模型 作者:tsing 本文地址:https://www.cnblogs.com/TssiNG-Z/p/17089759.html 简介 提起I/O模型, 就会说到同步/异步/阻塞/非阻 ...

  10. MyBatis的使用六(解决字段名与成员名不一致)

    本文主要讲述mybatis如何解决mysql的字段名与java实体类的成员变量名称不一致. 一. 介绍实体类和数据表 1. 实体类Employee public class Employee { pr ...