Spring MVC 教程-源码解析SpringMVC处理请求的流程

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

文将通过阅读源码的方式带大家了解springmvc处理请求的完整流程,干货满满。

1、先了解下SpringMVC常用的10组件

1.1、DispatcherServlet:前端控制器

这个大家是最熟悉的,是一个servlet,是springmvc处理请求的入口,不需要咱们开发,由框架提供。

作用:统一处理请求和响应,整个流程控制的中心,由它来调用其他组件处理用户的请求。

1.2、HandlerMapping:处理器映射器

作用:根据请求的信息(如url、method、header等)查找请求处理器,即找到自定义的controller中处理请求的方法。

HandlerMapping接口源码如下,getHandler:根据请求查找请求处理器,会返回一个HandlerExecutionChain对象。

    public interface HandlerMapping {
    	HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
    }

常见的实现类:

  • RequestMappingHandlerMapping:请求映射处理器映射,用来处理@RequestMapping定义的处理器的

1.3、HandlerExecutionChain:处理器执行链

HandlerMapping#getHandler方法会根据请求得到一个HandlerExecutionChain对象。

HandlerExecutionChain源码如下,主要包含了3个信息

  • handler:请求处理器,通常就是我们自定义的controller对象及方法
  • interceptorList:拦截器,当前请求匹配到的拦截器列表
  • interceptorIndex:拦截器索引,用来记录执行到第几个拦截器了
    public class HandlerExecutionChain {
    
    	private final Object handler;
    
    	private final List<HandlerInterceptor> interceptorList = new ArrayList<>();
    
    	private int interceptorIndex = -1;
    	
    }

1.4、handler:处理器

通常需要我们自己开发,一般指我们自定义的controller,在DispatcherServlet的控制下handler对具体的请求进行处理。

1.5、HandlerAdapter:处理器适配器

他负责对handler的方法进行调用,由于handler的类型可能有很多种,每种handler的调用过程可能不一样,此时就需要用到适配器HandlerAdapte,适配器对外暴露了统一的调用方式(见其handle方法),内部将handler的调用过程屏蔽了,HandlerAdapter接口源码如下,主要有2个方法需要注意:

  • supports:当前HandlerAdapter是否支持handler,其内部主要就是判HandlerAdapter是否能够处理handler的调用
  • handle:其内部负责调用handler的来处理用户的请求,返回返回一个ModelAndView对象
    public interface HandlerAdapter {
    
    	boolean supports(Object handler);
    
    	@Nullable
    	ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
    
    }

常见的实现类:

  • RequestMappingHandlerAdapter:其内部用来调用@RequestMapping标注的方法

1.6、ModelAndView:模型和视图

这个对象中主要用来存放视图的名称和共享给客户端的数据。

    public class ModelAndView {
    
    	/*视图*/
    	@Nullable
    	private Object view;
    
    	/*模型,用来存放共享给客户端的数据*/
    	@Nullable
    	private ModelMap model;
    	
    }

1.7、ViewResolver:视图解析器

这个是框架提供的,不需要咱们自己开发,它负责视图解析,根据视图的名称得到对应的视图对象(View)。

ViewResolver接口源码

    public interface ViewResolver {
    
    	@Nullable
    	View resolveViewName(String viewName, Locale locale) throws Exception;
    
    }

这个接口有很多实现类,比如jsp的、freemarker、thymeleaf的等,他们都有各自对应的ViewResolver。

而比较常的实现类是InternalResourceViewResolver,这个大家应该比较熟悉吧,目前为止我们前面的文章用到的都是这个视图解析器,用来处理jsp格式的视图页面,带大家再回顾一下这个类的配置,如下

    <!-- 添加视图解析器 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

InternalResourceViewResolver比较重要,这里说下这个类的resolveViewName方法获取视图的过程 ,大家也可以去阅读InternalResourceViewResolver#resolveViewName方法获得,大致的过程如下:

step1:判断视图viewName是否以redirect:开头,如果是,则返回RedirectView类型的视图对象,RedirectView是用来重定向的,RedirectView内部用到的是response.sendRedirect(url)进行页面重定向;否则继续向下step2

step2:判断viewName是否以forward:开头,如果是,则返回InternalResourceView类型的视图对象,InternalResourceView是用来做跳转的,InternalResourceView内部用到的是request.getRequestDispatcher(path).forward(request, response)进行页面跳转;否则继续向下step3

step3:判断当前项目是否存在jstl所需的类,如果是,则返回JstlView类型的视图,否则返回InternalResourceView类型的视图,这两个视图的render方法最终会通过request.getRequestDispatcher(path).forward(request, response)进行页面的跳转,跳转的路径是:InternalResourceViewResolver的前缀prefix + viewName+InternalResourceViewResolver的后缀prefix

1.8、View:视图

负责将结果展示给用户,View接口源码如下,render方法根据指定的模型数据(model)渲染视图,即render方法负责将结果输出给客户端。

    public interface View {
    	void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
    			throws Exception;
    }

View接口常见的2个实现类

  • RedirectView :负责重定向的,内部通过response.sendRedirect(url)进行页面重定向
  • InternalResourceViewResolver :负责页面跳转的,内部通过request.getRequestDispatcher(pa
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值