功能介绍

上篇文章【从源码角度了解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的执行流程有个更加具象的理解。

最新文章

  1. hdu 4704 Sum (整数和分解+快速幂+费马小定理降幂)
  2. jQuery删除节点和追加节点
  3. cocos2d-x 开头配置(Windows 平台)
  4. 软件工程随堂作业--随机产生30到四则运算(c语言)
  5. 《Python 学习手册4th》 第七章 字符串
  6. demo_04绘制三角形
  7. ThreadPoolExecutor详解
  8. yield return in C#
  9. 谢绝艳照门 - 手把手教你把当今很hit的家庭监控IP Camera变得网络安全起来
  10. CodeForces 510E Fox And Dinner
  11. Java 多线程并发编程之 Synchronized 关键字
  12. python手动设置递归调用深度
  13. 爬虫系列二(数据清洗---&gt;xpath解析数据)
  14. SharePoint 2010 在同意匿名訪问的站点中隐藏登陆链接
  15. Flutter - Migrate to AndroidX
  16. 自动化测试中CSS SELECTOR选择器的一些写法
  17. 异步IO的并发能力:backlog的配置很重要
  18. 优化算法动画演示Alec Radford&#39;s animations for optimization algorithms
  19. Java单播、广播、多播(组播)
  20. caffe安装编译问题-ImportError: No module named caffe

热门文章

  1. jackson java转json hibernate懒加载造成的无限递归问题
  2. Mac下SVN基本操作和常见错误
  3. UVA 11212 Editing a Book [迭代加深搜索IDA*]
  4. Java内存溢出java.lang.OutOfMemoryError: PermGen space
  5. Comb CodeForces - 46E (动态规划)
  6. Python_全局变量的定义
  7. VMware Workstation 与 Device/Credential Guard 不兼容.在禁用 Device/Credenti
  8. JMM中的Happens-Before原则
  9. 网络OSI七层架构与TCP四层架构的应用与区别
  10. 深入浅出 Viewport 设计原理