通过自己实现接口来加深理解SpringMVC的执行流程
功能介绍
上篇文章【从源码角度了解SpringMVC的执行流程】通过接口源码向大家介绍了SpringMVC的执行流程,主要偏重于源码。这篇文件我们来自己实现那几个关键接口,来真实体验下SpringMVC关键的流程,以此来加深理解。功能很简单,通过访问一个地址 /mymvc 来自动跳转到工程首页,但是我们不用SpringMVC自带的Controller等组件,完全自己手动开发。工程结构如下图

代码流程
将自定义的实现类放入Ioc容器中。
@Configuration
public class MyConfig {
@Bean
public HandlerMapping myHandlerMapping() {
return new MyHandlerMapping();
}
@Bean
public HandlerAdapter myHandlerAdapter() {
return new MyHandlerAdapter();
}
@Bean
public ViewResolver myViewResolver() {
return new MyViewResolver();
}
}
获取处理器

获取实现了HandlerMapping接口的类调用getHandler获取handler。
下面的代码是自定义HandlerMapping继承于AbstractHandlerMapping 。其中AbstractHandlerMapping 实现了HandlerMapping接口。这也是代码通常的结构。定义一个接口,抽象类实现接口完善一些基础代码,并将那些可以扩展的功能再暴露出去,这样我们再开发时只需要关注自己扩展的功能即可,不需要将接口所有的方法都再实现一遍,大大减少了开发成本。
新建自定义的处理器MyHandler返回。这里有一点需要注意,就是需要设置排序号,否则SpringMVC会先执行SimpleUrlHandlerMapping,这个类作为SpringMVC中最后执行的类,如果没有找到处理器,则会返回异常,所以自定义的HandlerMapping排序号必须大于这个类的排序号,先于此类执行。
public class MyHandlerMapping extends AbstractHandlerMapping {
@Override
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
Object handler = null;
String requestUri = getUrlPathHelper().getRequestUri(request);
if (requestUri.equals("/mymvc")) {
handler = new MyHandler();
}
return handler;
}
@Override
public int getOrder() {
return 1;
}
}
获取处理器对应的适配器

获取实现了HandlerAdapter接口的类调用supports判断适配器是否适配上面获取的处理器,为什么会有适配器这一层逻辑上篇代码也介绍过了。
下面代码为自定义HandlerAdapter,supports逻辑很简单,判断处理器类型是否为MyHandler。
public class MyHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
if (handler instanceof MyHandler) {
return true;
}
return false;
}
适配器调用处理器
调用自定义处理器的handler方法,返回逻辑视图名,并封装为ModelAndView。
public class MyHandlerAdapter implements HandlerAdapter {
@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
MyHandler myHandler = (MyHandler) handler;
String result = myHandler.handler();
ModelAndView mv = new ModelAndView();
mv.setViewName(result);
return mv;
}
自定义处理器,返回 myview 作为逻辑视图名。
public class MyHandler {
public String handler() {
return "myview";
}
}
解析视图
判断逻辑视图名为 myview 新建视图返回。
public class MyViewResolver implements ViewResolver {
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
View view = null;
if ("myview".equals(viewName)) {
view = new MyView();
}
return view;
}
}
渲染视图
直接跳转到首页。
public class MyView implements View {
@Override
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
String path = "http://localhost:8080/";
response.sendRedirect(path);
}
@Override
public String getContentType() {
return "text/html;charset=ISO-8859-1";
}
}
结语
上面代码逻辑很简单,大家也可以照着这个思路自己动手开发自定义的扩展功能,自己DUBUG体会一下整体流程,我相信会对SpringMVC的执行流程有个更加具象的理解。
通过自己实现接口来加深理解SpringMVC的执行流程的更多相关文章
- 从源码角度了解SpringMVC的执行流程
目录 从源码角度了解SpringMVC的执行流程 SpringMVC介绍 源码分析思路 源码解读 几个关键接口和类 前端控制器 DispatcherServlet 结语 从源码角度了解SpringMV ...
- 《SpringMVC从入门到放肆》二、SpringMVC的执行流程及默认配置
上一篇博文我们做了一个hello world的程序,并且已经成功的跑起来了.这一篇我们来深入的了解一下SpringMVC的执行流程以及一些其它的配置. 一.执行流程 来解释一下上图中的各个名词1.Di ...
- springMVC的执行流程和完整代码
一.什么是 Spring MVC Spring MVC 属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 里面,是一个强大灵活的 Web 框架.Spring ...
- Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程
在本系列的上一篇文章中,我们学习了Glide的基本用法,体验了这个图片加载框架的强大功能,以及它非常简便的API.还没有看过上一篇文章的朋友,建议先去阅读 Android图片加载框架最全解析(一),G ...
- springmvc的执行流程详解
1.什么是MVC MVC是Model View Controller的缩写,它是一个设计模式 2.springmvc执行流程详细介绍 第一步:发起请求到前端控制器(DispatcherServlet) ...
- SpringMVC的执行流程
解析SpringMVC执行流程 SpringMVC的执行图大概如下所示 1.首先它是由客户端发起请求,到DispatcherServlet,被拦截后到HandlerMapping这里充当一个路由器,通 ...
- springMvc的执行流程(源码分析)
1.在springMvc中负责处理请求的类为DispatcherServlet,这个类与我们传统的Servlet是一样的.我们来看看它的继承图 2. 我们发现DispatcherServlet也继承了 ...
- Spring MVC入门(一)—— SpringMVC的执行流程与常用注解
一.什么是SpringMVC SpringMVC就是类似于Struts2的mvc框架,属于SpringFrameWork的后续产品.在模型层中与视图层的交互部分. springMVC执行流程: 二.常 ...
- SpringMVC——MVC执行流程底层剖析
SpringMVC流程图如上面所示,根据上图,串联一下底层源码: 1.在DispatcherServlet中找到doDisPatch 2.观察方法体,然后找到getHandler方法 3.点进方法,发 ...
随机推荐
- tf.variance_scaling_initializer() tensorflow学习:参数初始化
CNN中最重要的就是参数了,包括W,b. 我们训练CNN的最终目的就是得到最好的参数,使得目标函数取得最小值.参数的初始化也同样重要,因此微调受到很多人的重视,那么tf提供了哪些初始化参数的方法呢,我 ...
- VMware 注册码
VMware 12 Pro 永久许可证激活密钥 5A02H-AU243-TZJ49-GTC7K-3C61NVF5XA-FNDDJ-085GZ-4NXZ9-N20E6UC5MR-8NE16-H81WY- ...
- 【codeforces 789B】Masha and geometric depression
[题目链接]:http://codeforces.com/contest/789/problem/B [题意] 让你一个一个地写出等比数列的每一项 (注意是一个一个地写出); 有m个数字不能写; 且数 ...
- windows命令行下redis读取中文字符乱码
我在eclipse上对redis进行了一个操作,添加了一个中文字符串进去,可以看到是添加成功了的 但是在命令行中读取的时候却成了乱码,如下图所示 这是因为windows命令行的编码是gbk 可以通过如 ...
- springboot上传文件时500错误,提示临时目录无效
org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nes ...
- JUnit 单元测试断言推荐 AssertJ
文章转自:http://sgq0085.iteye.com/blog/2030609 前言 由于JUnit的Assert是公认的烂API,所以不推荐使用,目前推荐使用的是AssertJ. Assert ...
- 常用MouseEvent鼠标事件对象&KeyboardEvent键盘事件对象&常用键盘码
MouseEvent鼠标事件对象: e.target //=> 事件源(操作的是哪个元素) e.clientX e.clientY //当前鼠标触发点距离当前窗口左上角的X|Y轴坐标 e.pag ...
- 螺旋矩阵O(1)根据坐标求值
传送门 洛谷2239 •题意 从矩阵的左上角(第11行第11列)出发,初始时向右移动: 如果前方是未曾经过的格子,则继续前进,否则右转: 重复上述操作直至经过矩阵中所有格子. 根据经过顺序,在格子中依 ...
- boostrap-非常好用但是容易让人忽略的地方【4】:Font Awesome
font-awesome基本用法 官方代码传送门 font-awesome在bootstrap中的特殊用法(这个才是重点) 要点归纳1(官方) 官方代码传送门 要点归纳2(我的) <a href ...
- Spring Boot 整合 slf4j+log4j2 实现日志管理
背景 Java 中比较常用的日志框架: log4j(Log for Java):Apache 的一个开源项目,七种日志级别:OFF.FATAL.ERROR.WARN.INFO.DEBUG.TRACE ...