Spingmvc中的HandlerMapping剖析

 更新时间:2023年09月09日 10:11:11   作者:沐雨金鳞  
这篇文章主要介绍了Spingmvc中的HandlerMapping剖析,Spingmvc中的HandlerMapping负责解析请求URL,对应到Handler进行处理,这里的Handler一般为Controller里的一个方法method,也可以为servlet或者Controller等,需要的朋友可以参考下

HandlerMapping

1、请求首先进入DispatcherServlet, 由DispatcherServlet 从HandlerMappings中匹配对应的Handler,此时只是获取到了对应的Handler,然后拿着这个Handler去寻找对应的适配器,即:HandlerAdapter;

2、拿到对应HandlerAdapter时,这时候开始调用对应的Handler方法,即执行我们的Controller来处理业务逻辑了, 执行完成之后返回一个ModeAndView;

3、HandlerAdapter执行完之后,返回一个ModeAndView,把它交给我们的视图解析器ViewResolver,通过视图名称查找出对应的视图然后返回;

4、最后,渲染视图 返回渲染后的视图。

在介绍HandlerMapping、HandlerAdapter之前,先来说一下SpringMVC中定义Handler的方式,本人就是对这个知识点不熟悉,导致对这两个对象一直不明白。

先说一下最最最最……常用定义Handler的方式,使用@RequestMapping注解,下面这段代码不用介绍吧:

@Controller
public class IndexController {
    @RequestMapping("/index")
    @ResponseBody
    public String sayHello(){
        System.out.println("hello ...");
        return "hello";
    }
}

那大家有没有用过下面的两种方式来声明一个Handler呢??

实现org.springframework.web.servlet.mvc.Controller控制器接口,此接口只有一个方法handleRequest(),用于请求的处理,返回ModelAndView。 这个接口从第一版SpringMVC就存在了,所以这个接口是非常古老的接口~~~也是Spring MVC最早期的实现Handler的方式

// 关注一下这个包
import org.springframework.web.servlet.mvc.Controller;
@Component("/home")
public class HomeController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, 
    				HttpServletResponse response) throws Exception {
        System.out.println("home ...");
        return null;
    }
	// 这地方考虑个问题:怎么样实现类似@ResponseBody的功能呢?
	// 就是想实现直接向body里写数据,而不是返回一个页面。
	// 如果想直接在处理器/控制器里使用response向客户端写回数据,
	// 可以通过返回null来告诉	DispatcherServlet我们已经写出响应了,
	// 不需要它进行视图解析。像下面这样
	@Override
    public ModelAndView handleRequest(HttpServletRequest request,
    				 HttpServletResponse response) throws Exception {
        System.out.println("home ...");
        response.getWriter().write("home controller from body");
        return null; // 返回null告诉视图渲染  直接把body里面的内容输出浏览器即可
    }
}

Spingmvc中的HandlerMapping负责解析请求URL,对应到Handler进行处理(这里的Handler一般为Controller里的一个方法method,也可以为servlet或者Controller等)

来看一个http请求的入口DispatcherServlet:

  • DispatcherServlet继承FrameworkServlet,FrameworkServlet继承HttpServletBean,HttpServletBean继承HttpServlet。

可以看出,springmvc的DispatcherServlet是在Servelt的基础上做了扩展处理。

doService方法为servlet处理请求的入口,DispatcherServlet中做了方法覆盖,doService方法中的doDispatch(request,response)方法,是springmvc处理整个请求流程的关键。

  • mappedHandler =getHandler(processedRequest);
  • 这行代码实现了为请求寻找处理handler,返回的是HandlerExecutionChain;
  • HandlerAdapter ha =getHandlerAdapter(mappedHandler.getHandler());
  • 找到处理handler后,再去找匹配的HandlerAdapter,HandlerAdapter将完成后续处理。

继续看是如何找到请求对应的处理handler的:

  • 可以看出是从类变量this.handlerMappings中循环获取,当找到与之匹配的HandlerMapping时,返回类型为HandlerExecutionChain的handler。

这里this.handlerMappings中的值是从哪获取的呢?DispatcherServlet初始化的时候会给this.handlerMappings赋值:

  • 从这里可以看出,在servlet初始化的时候,会对springmvc的HandlerMappings、HandlerAdapters等做初始化。
  • 这里三个步骤,先对springmvc.xml里配置的HandlerMapping进行初始化、实例化,再对this.handlerMappings赋值,最后对this.handlerMappings进行排序。
  • 这里的排序就是对HandlerMapping的order属性进行排序,这样,order属性值小的,就可以先对请求进行匹配。
  • 从tomcat启动日志里可以看到HandlerMapping的初始化:

 这里涉及到两个HandlerMapping:

  • 第一个是BeanNameUrlHandlerMapping,初始化时会将urlpath做映射存储;
  • 第二个是RequestMappingHandlerMapping,初始化时会将Controller中配置@RequestMapping注解的方法做映射存储。

HandlerMapping初始化时,会将映射与handler存储到map里;处理请求时,从map里取出对应的处理handler。

这就是HandlerMapping在springmvc里的大致处理流程。

到此这篇关于SpringBoot中的HandlerMapping剖析的文章就介绍到这了,更多相关SpringBoot的HandlerMapping内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • IDEA创建Java Web项目的超详细图文教学

    IDEA创建Java Web项目的超详细图文教学

    IDEA是程序员们常用的java集成开发环境,也是被公认为最好用的java开发工具,下面这篇文章主要给大家介绍了关于IDEA创建Java Web项目的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • Spring Boot加载配置文件的完整步骤

    Spring Boot加载配置文件的完整步骤

    这篇文章主要给大家介绍了关于Spring Boot加载配置文件的完整步骤,文中通过示例代码介绍的非常详细,对大家的学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-11-11
  • Java零基础精通方法篇

    Java零基础精通方法篇

    方法,也称函数,如果想要重复一段或者多段代码块的使用,可以将这些代码封装成一个方法,方法具体表现为某种行为,使用方法可以提高代码的复用性
    2022-05-05
  • Java日常练习题,每天进步一点点(60)

    Java日常练习题,每天进步一点点(60)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-08-08
  • java实现轻轻松松控制台斗地主的示例代码

    java实现轻轻松松控制台斗地主的示例代码

    这篇文章主要介绍了java实现轻轻松松控制台斗地主,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • java分页拦截类实现sql自动分页

    java分页拦截类实现sql自动分页

    这篇文章主要为大家详细介绍了java分页拦截类可以实现sql自动分页,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • Java冒泡排序法和选择排序法的实现

    Java冒泡排序法和选择排序法的实现

    这篇文章主要介绍了Java冒泡排序法和选择排序法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • 浅谈java中null是什么,以及使用中要注意的事项

    浅谈java中null是什么,以及使用中要注意的事项

    下面小编就为大家带来一篇浅谈java中null是什么,以及使用中要注意的事项。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Spring Boot和Docker实现微服务部署的方法

    Spring Boot和Docker实现微服务部署的方法

    这篇文章主要介绍了Spring Boot和Docker实现微服务部署的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • 使用XML配置c3p0数据库连接池

    使用XML配置c3p0数据库连接池

    这篇文章主要为大家详细介绍了使用XML配置c3p0数据库连接池,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08

最新评论