2019独角兽企业重金招聘Python工程师标准>>>

在开发以Springmvc为框架的web应用中,我们经常会看到web.xml既配置了ContextLoaderListener监听器,又配置了名为DispatcherServlet的Servlet,我们知道DispatcherServlet可以看作springmvc程序的入口,前端的请求提交给DispatcherServlet后,它会寻找对应的HandlerMapping,继而找到处理器。处理器进行相关的业务处理,返回模型与视图,DispatcherServlet通过视图解析器将ModelAndView进行处理之后返回给前端。

要弄懂他们俩的作用及区别,最好的方式就是去分析他们的源码,知其表里,才能在理解与使用的层次上提高一个水平。

先来看看ContextLoaderListener的实现:

通过上面代码可以看出ContextLoaderListener继承了ContextLoader类并实现了ServletContextListener接口,ServletContextListener接口能够监听ServletContext的变化。我们知道基于Servlet的web服务器,在服务器启动时ServletContext会被创建,在服务器关闭时ServletContext会被销毁,所以实现了ServletContextListener接口的类就能在服务启动或关闭时处理一些事情。

那么ContextLoaderListener就是通过父类的initWebApplicationContext()方法来初始化上下文。上下文可以理解为一块独立的内存空间,里面可以包含各种bean资源、对象资源,这些资源可以被上下文独享、也可以共享给其他的上下文。打个比方,可以把上下文看做是一个球队,各种资源可以看成球队里的运动员,球队里的队员可以外派给其他球队,当然也有核心球员只能被自己的球队使用。球队与球队之间可以建立联盟关系,这样资源就可以共享。大概意思就是这样,每个人的理解都可能不一样,回归正题。再看下initWebApplicationContext()方法的实现。

首先会去ServletContent里找名为org.springframework.web.context. WebApplicationContext.ROOT的上下文对象,如果存在抛异常提示已经存在。如果不存在会调用createWebApplicationContext(servletContext)方法来创建。

继续来看createWebApplicationContext方法,该方法首先会调用determineContextClass方法,该方法会先从上下文初始化参数里找名为CONTEXT_CLASS_PARAM对应的值,该值其实就是上下文类名,可以在web.xml中配置。找到了就创建对应的上下文类对象,找不到就从defaultStrategies对象中获取。来看看defaultStrategies对象,它会在ContextLoader类加载的时候被初始化,读取ContextLoader类路径下ContextLoader.properties属性文件中的值放到defaultStrategies对象中。

看下ContextLoader.properties内容,我们就知道在web.xml中配置以下内容也可以完成上下文对象的创建。

创建好的上下文最终会放到属性名为org.springframework.web.context. WebApplicationContext.ROOT的ServletContext中。

接下来看看DispatcherServlet的实现:

如上面类的层次结构图所示,DispatcherServlet继承自HttpServletBean,在web容器启动时会调用HttpServletBean的init()方法,查看代码发现在init()方法里会调用initServletBean()方法,该方法默认实现为空,所以在子类重载该方法就可以在web容器启动时做一些工作。

再查看FrameworkServlet的initServletBean()的方法,可以看到在该方法里会调用initWebApplicationContext()方法来完成WebApplicationContext的初始化。查看initWebApplicationContext()方法,我们可以了解到程序会先去ServletContext里找名为org.springframework.web.context. WebApplicationContext.ROOT的上下文,如果在web.xml里定义了ContextLoaderListener监听器,那么此处的rootContext就不为空。接下来可以看到findWebApplicationContext()方法,该方法会从ServletContext里找你在web.xml里配置的contextAttribute参数值对应的attribute。故如下图,同时配置了ContextLoaderListener,那么DispatcherServlet创建的上下文就和ContextLoaderListener创建上下文就完全一样了。

如果没有配置contextAttribute参数或者配置了contextAttribute参数,但是在ServletContext里没有找到对应的上下文,接着会调用createWebApplicationContext()方法来创建应用上下文,其参数为上面的rootContext,这里的rootContext的作用其实就是设置其作为创建好的上下文的父上下文。具体的创建过程在这里不再赘述,至此DispatcherServlet创建的上下文结束。

从上面ContextLoaderListener和DispatcherServlet的加载过程我们可以看出,ContextLoaderListener创建的上下文会和DispatcherServlet创建的上下文是父子关系。所以ContextLoaderListener一般会加载整个Spring容器相关的bean配置,如:Dao、Service、Log、DataSource、一些属性配置文件等,而DispatcherServlet一般会加载MVC相关的bean配置,如: ViewResolver, Controller, MultipartResolver, ExceptionHandler等。

原文地址:https://zero502.com/zero/article.jl?aId=39

转载于:https://my.oschina.net/jiangli0502/blog/1824060

【Spring】详解ContextLoaderListener和DispatcherServlet的区别相关推荐

  1. MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测)

    MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测) 一.什么是表分区 通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了. 如:某用户表的记录超过 ...

  2. Mysql存储引擎详解(MyISAM与InnoDB的区别)

    Mysql存储引擎详解(MyISAM与InnoDB的区别) 存储引擎     MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平 ...

  3. mysql 社区版 innodb_MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测)

    MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测) / --------------------         写在最前面            ------------------ ...

  4. 详解http和https的区别

    详解http和https的区别 (转自http://www.jzxue.com/jianzhanzhinan/jianzhanrumen/201103/29-6925.html) http与https ...

  5. Spring 详解(五):Spring声明式事务

    事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性.本文主要讲解事务涉及到一些概念以及spring中事务的使用. 1. 事务 数据库事务(Database Transaction) ...

  6. Spring 详解(四):Spring MVC

    1. 跟踪Spring请求 使用Spring构建的Web程序中,请求最先接触到的是Spring中的DispatcherServlet.从图中可以看见DispatcherServlet相当一个调度者,所 ...

  7. 算术编码例题详解_百分数与百分点区别详解

    通过以往的答疑经验,许多同学对于出现百分点的材料和题目不能够很好的百分点与已知百分数之间的关系.那么百分数与百分点的核心区别在哪里?常见题型中出现的百分数与百分点应该如何进行理解应用? 百分数与百分点 ...

  8. java中$和 的区别详解_Mybatis之#{}与${}的区别使用详解

    1.两种取值方式的差异 mapper.xml映射文件 select * from t_emp WHERE emp_id=${id} and emp_name=#{name} java查询代码 para ...

  9. 七、Vue cli详解学习笔记——什么是Vue cli ,Vue cli的使用(安装,拉取2.x模板,初始化项目),Vue cli2详解,Runtime-Compiler和Runtime-only区别

    一.什么是Vue CLI 如果你只是简单写几个Vue的Demo程序, 那么你不需要Vue CLI. 如果你在开发大型项目, 那么你需要, 并且必然需要使用Vue CLI 使用Vue.js开发大型应用时 ...

最新文章

  1. 提高页面载入速度简单易行的四个办法。
  2. Java面向接口编程,低耦合高内聚的设计哲学
  3. 开了gomod不识别gopath_三分钟掌握Go mod常用与高级操作
  4. 2016年第6本:简约至上--交互式设计四策略
  5. 利用递归求某数的阶乘——C/C++
  6. java mysql实现原理_MySQL事务实现原理
  7. php session页面传值,PHP session在页面间传递的问题
  8. 括号里面一个上面一个数下面一个数符号怎么打?/ 概率论组合符号怎么打?
  9. Java扫雷游戏的设计与实现毕业设计论文
  10. python snownlp了解_python中snownlp情感分析简易的demo分享
  11. Windows安装GoldenDict
  12. flutter与RN对比
  13. 消息重试框架 Spring-Retry 和 Guava-Retry,这个框架有点意思
  14. python实现三级菜单_Python3.5实现的三级菜单功能示例
  15. python求excel平均值_python帮助计算excel文件上的平均值和std
  16. 常见html的标签含义(2)
  17. python属于计算机的什么语言_Python语言属于()_学小易找答案
  18. omv检查硬盘坏道_关于怎么用MHDD修复硬盘坏道
  19. 磁盘存储和文件系统管理
  20. LINQ分组查询—GroupBy()

热门文章

  1. Android 学习心得(2)——Android内置数据库SQLite
  2. javascript优化--01高质量编码
  3. StretchBlt()函数使用
  4. 大数据之-Hadoop3.x_MapReduce_开发总结---大数据之hadoop3.x工作笔记0137
  5. 微服务升级_SpringCloud Alibaba工作笔记0005---spring gateway非阻塞异步模型
  6. STM32工作笔记0047--认识DTU什么是4GDTU设备
  7. FastDfs工作笔记002---SpringBoot集成FastDfs
  8. JAVA面试要点009---TimeUnit用法
  9. Linux工作笔记029---Centos7.3 服务器下查看tomcat服务是否启动,重启,查看错误日志等基本操作
  10. 车牌颜色识别现在的结果