当前位置: 首页 > news >正文

Spring技术内幕笔记(2):Spring MVC 与 Web

Spring MVC 与 Web

IoC容器与Web容器的关系

ServletContext为IoC容器提供了宿主环境。IoC容器通过ContexLoaderListener初始化建立,ContexLoaderListener是注册在Web容器中的监听器,当Web容器初始化时,监听器会收到该事件从而发起Spring容器的初始化。DispatchServlet是Spring MVC处理请求的转发器,从而响应HTTP的请求。

ContexLoaderListener会调用ContextLoader,ContextLoader又会创建XmlWebApplicationContext,XmlWebApplicationContext作为默认的IoC容器,负责从默认的/WEB-INF/applicationContext.xml中加载BeanDefinition。

ContextLoader在创建IoC容器XmlWebApplicationContext后会将其注册入servletContext的属性ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE中。

DispatchServlet的功能

DispatchServlet负责两个工作,根据web.xml初始化自己的上下文,响应http请求。

在ContextLoader加载完成后,开始DispatchServlet的初始化。首先从ServletContext中获取WebApplicationContext作为双亲上下文,这里就是XmlWebApplicationContext,所以XmlWebApplicationContext定义的Bean可以被DispatchServlet获取,在DispatchServlet中查找Bean时,会首先从双亲上下文中查找。获取双亲上下文后,DispatchServlet会创建自己的上下文,并且将其注册进ServletContext的属性中,属性名为该servlet相关的,因为一个Web容器可以有多个servlet。

DispatchServlet上下文的初始化后会开始创建一些请求处理策略,如LocalResolver、HandlerMappings等。例如,初始化HandlerMappings就是从IoC容器中获取所有的HandlerMapping相关的Bean。

HandlerMapping是对HTTP请求到controller的映射,HandlerMapping根据请求获取一个HandlerExecutionChain,其中包含了一个handler和多个interceptor,interceptor负责功能的增强。

例如SimpleUrlHandlerMapping在初始化时会将url和对应handler的bean放入map中保存。当请求到达时,会从SimpleUrlHandlerMapping中查找最长匹配url的handler,包装成HandlerExecutionChain返回。

DispatchServlet处理请求的过程

当请求到来,从所有的HandleMapping中依次查找到匹配的HandlerExecutionChain,多个HandleMapping是按照优先级排序的。

HandlerExecutionChain获得后,先对请求执行intercepter的preHandler,然后执行handler,最后再次执行intercepter的postHandler,得到最终的ModelAndView对象。

最后根据ModelAndView渲染视图并返回。

ModelAndView呈现给客户端的过程

以JSP视图为例。

Step1:ModelAndView获得后,会从中获取其对应的View,也就是根据ModelAndView指明的名称获得对应View的Bean。

Step2:View接着将数据进行合并,然后将数据放入requst中进行暴露。

Step3:根据请求,获取URL路径,定位资源。如JSP文件。

Step4:将包含数据的requst转发到目标资源路径,由web容器负责获取资源,并且将数据装入JSP。最后将拼装好的文件返回。

相关文章:

  • saltstack安装
  • 徒手撸UI之DatePicker
  • 常用链接收藏
  • TPYBoard获取MicroPython提示
  • Esper复杂事务处理一小时入门
  • 第204天:js---重载和多态
  • 【资源共享】5G AP分析
  • webpack4.0入门以及使用
  • Node总结
  • Unity中的平移 缩放 旋转
  • android开发学习 ------- 【转】 android中的单例模式 (详解)
  • python学习笔记(数据类型)
  • P1073 最优贸易
  • 080.mycat和mycopy
  • [模板] LIS
  • angular学习第一篇-----环境搭建
  • ES6简单总结(搭配简单的讲解和小案例)
  • ES6系列(二)变量的解构赋值
  • flask接收请求并推入栈
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • java2019面试题北京
  • laravel 用artisan创建自己的模板
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • nodejs调试方法
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 面试总结JavaScript篇
  • 模型微调
  • 设计模式走一遍---观察者模式
  • 听说你叫Java(二)–Servlet请求
  • 微信小程序开发问题汇总
  • nb
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • ​iOS安全加固方法及实现
  • #Linux(make工具和makefile文件以及makefile语法)
  • (黑马C++)L06 重载与继承
  • (循环依赖问题)学习spring的第九天
  • .NET关于 跳过SSL中遇到的问题
  • .NET微信公众号开发-2.0创建自定义菜单
  • @reference注解_Dubbo配置参考手册之dubbo:reference
  • [ element-ui:table ] 设置table中某些行数据禁止被选中,通过selectable 定义方法解决
  • [BUG] Authentication Error
  • [C#] 如何调用Python脚本程序
  • [C++数据结构](31)哈夫曼树,哈夫曼编码与解码
  • [CareerCup] 6.1 Find Heavy Bottle 寻找重瓶子
  • [CISCN2021 Quals]upload(PNG-IDAT块嵌入马)
  • [cocos creator]EditBox,editing-return事件,清空输入框
  • [delphi]保证程序只运行一个实例
  • [docker]docker网络-直接路由模式
  • [English]英语积累本
  • [Flutter]设置应用包名、名称、版本号、最低支持版本、Icon、启动页以及环境判断、平台判断和打包
  • [hihocoder1395] 最大权闭合子图
  • [iHooya]2023年1月30日作业解析
  • [Java]快速入门二叉树,手撕相关面试题
  • [JavaWeb学习] Spring Ioc和DI概念思想