热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

SpringMVC的源码解析

本文主要介绍了SpringMVC的源码解析。具有很好的参考价值,下面跟着小编一起来看下吧

学习java的人都知道spring,springMVC,mybatis等框架,像structs2这样的框架是基于servlet以外实现的,而springMVC是基于servlet容器实现的,

本文将分析SpringMVC的核心分发器DispatcherServlet的初始化过程以及处理请求的过程,让读者了解这个入口Servlet的作用。

在分析DispatcherServlet之前,我们先看下DispatcherServlet的继承关系,

HttpSerlvetBean继承自HttpServlet。

HttpServletBean覆写了init方法,对初始化过程做了一些处理。 以下是初始化的代码:

首先,ServletConfigPropertyValues是HttpServletBean的静态类,构造过程会使用ServletConfig对象找出web.xml文件中配置参数,并设置到ServletConfigPropertyValue,使用BeanWrapper来构造DispatcherServlet, 获取ServletContextResourceLoader的资源加载器,然后注册资源编辑器,初始化BeanWrapper对象,设置DispatcherServlet属性,默认初始化ServletBean不做任何处理,子类覆盖该方法可以做任何事情,

以下是web.xml文件配置:

这段配置初始化参数为contextConfigLocation,后来构造的是BeanWrapper对象, 由于contextConfigLocation在FrameworkServlet中定义,但是没有在HttpServletBean中定义,利用Spring的注入特性,只需要调用setContextConfigLocation方法,就可以将contextConfigLocation设置到对应的实例当中,然后设置DispatcherServlet中contextConfigLocation(FrameworkServlet中定义)的属性,为web.xml读取contextConfigLocation参数,该资源文件用构造SpringMVC的容器的上下文。

下面看下FrameworkServlet这个类,FrameworkServlet继承自HttpServletBean。

以下是initServletBean的代码:

首先第一步是初始化WebApplicationContext,它是继承于ApplcationContext的接口,ApplcationContext是Spring容器的上下文,Servlet和Spring容器关联的作用,然后初始化FrameWorkServlet,其实它空的,什么也做,子类重写这个方法,可以做任何处理,不过DispatcherServlet并重写这个方法。

下面是初始化initWebApplicationContext的具体实现逻辑: 

    

首先,得到根路径,DistpatcherServlet有个WebApplication为参数的构造函数,如果注入了WebApplication 这个对象,就会执行上图代码。

FrameworkServlet中有个String类型的contextAttribute的变量名,以它为key在ServletContextWebApplicationContext,一般不会设置,contextAttribute属性,也就说,wac开始是null;接下来就是创建WebApplicationContext,并设置根上下文为父上下文,然后配置ServletConfig,ServletContext等到这个上下文,这个类中有个函数onReFresh是一个模版方法,在WebApplication成功创建后就会调用,FrameworkServlet的实现类,就会重写这个方法,并将创建的容器上下文设置到ServletContext中,这里的根上下文是web.xml中配置的ContextLoaderListener监听器中根据contextConfigLocation路径生成的上下文。

比如这段配置文件中根据classpath:context-*.xml下的xml文件生成的根上下文。

接着看一下DispatcherServlet重写了FrameworkServlet中onReFresh方法,

可以看到initStrategies方法中,在初始化各种各种策略接口的实现类, 后面再一一分析各个策略接口的实现的详细介绍。

总结一个三个类的作用:

HttpServletBean 主要做一些初始化的工作,将web.xml中配置的参数设置到Servlet中。比如servlet标签的子标签init-param标签中配置的参数。

FrameworkServlet 将Servlet与Spring容器上下文关联。其实也就是初始化FrameworkServlet的属性webApplicationContext,这个属性代表SpringMVC上下文,它有个父类上下文,web.xml中配置的ContextLoaderListener监听器初始化的容器上下文。

DispatcherServlet 主要是初始化一些各个策略接口的实现。比如请求处理,试图处理。处理的适配等。

DispatcherServlet请求处理过程:

先看下HttpServlet提供的方法用于处理请求,service使用了模版模式,对于HttpServlet的get请求,调用doGet方法,post请 求,调用doPost方法........

在看下处理processRequest函数

首先,获取于当前线程绑定的LocaleContext和ServletRequestAttributes对象,initContextHoers函数就是让新构造的LocaleContex和requestAttributes进行关联,这个关联使用ThreadLocal完成,doService方法是抽象方法,具体由DispatcherServlet实现。

最后调用resetContextHolders函数重置LocaleContext和RequestAttribute对象,解除LocaleContext和RequestAttribute对象的绑定。执行成功后,发布ServletRequestHandlerEvent事件,可以通过注册监听器来监听该事件的发布。注册的监听器类型为ApplicationListener接口类型。

接下来是DispatcherServlet的doService方法.

如果该请求是include的请求,那么保留一份快照版本的request域中的数据,doDispatch方法之后,这个快照版本的数据将会覆盖新的Requet域的数据。  

然后在request中设置一些属性,最后doDispatcher进行请求分发处理。      

doDispatch方法功能大致过程如下:

首先根据请求的路径,通过RequestMapping的注解映射,找到HandlerMethod(也就是对应Controller中的方法),然后匹配路径对应的拦截器,有了HandlerMethod和拦截器构造个HandlerExecutionChain对象。HandlerExecutionChain对象的获取是通过HandlerMapping接口提供的方法中得到。

有了HandlerExecutionChain之后,通过handlerAdapter对象进行适配处理,得到ModelAndView对象,HandlerMethod内部handle的时候,使用各种HandlerMethodArgumentResolver实现类处理HandlerMethod的参数,使用各种HandlerMethodReturnValueHandler实现类处理返回值,最终返回值被处理成一个ModelAndView对象,这期间发生的异常会被HandlerExceptionResolver接口实现类进行处理.

总结: 本文主要分析DispatcherServlet及其父类FrameworkServlet和HttpServletBean它们的作用。以及一个请求到处理返回,大致过程的分析。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


推荐阅读
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • SpringMVC工作流程概述
    SpringMVC工作流程概述 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 本文介绍了一个免费的asp.net控件,该控件具备数据显示、录入、更新、删除等功能。它比datagrid更易用、更实用,同时具备多种功能,例如属性设置、数据排序、字段类型格式化显示、密码字段支持、图像字段上传和生成缩略图等。此外,它还提供了数据验证、日期选择器、数字选择器等功能,以及防止注入攻击、非本页提交和自动分页技术等安全性和性能优化功能。最后,该控件还支持字段值合计和数据导出功能。总之,该控件功能强大且免费,适用于asp.net开发。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 本文介绍了Cocos2dx学习笔记中的更新函数scheduleUpdate、进度计时器CCProgressTo和滚动视图CCScrollView的用法。详细介绍了scheduleUpdate函数的作用和使用方法,以及schedule函数的区别。同时,还提供了相关的代码示例。 ... [详细]
  • Jboss的EJB部署描述符standardjaws.xml配置步骤详解
    本文详细介绍了Jboss的EJB部署描述符standardjaws.xml的配置步骤,包括映射CMP实体EJB、数据源连接池的获取以及数据库配置等内容。 ... [详细]
  • 引号快捷键_首选项和设置——自定义快捷键
    3.3自定义快捷键(CustomizingHotkeys)ChemDraw快捷键由一个XML文件定义,我们可以根据自己的需要, ... [详细]
  • 编码_QML 编码约定
    本文由编程笔记#小编为大家整理,主要介绍了QML编码约定相关的知识,希望对你有一定的参考价值。 ... [详细]
author-avatar
mobiledu2502918487
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有