DispatcherServlet的启动和初始化
DispatcherServlet的初始化与Servlet的初始化相关联。DispatcherServlet的初始化是在其基类HttpServletBean中做的。init中的initServletBean是在其子类FrameworkServlet中实现的。initServletBean会创建上下文。
public final void init() throws ServletException {if (logger.isDebugEnabled()) {logger.debug("Initializing servlet '" + getServletName() + "'");}// Set bean properties from init parameters.PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);if (!pvs.isEmpty()) {try {BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));initBeanWrapper(bw);bw.setPropertyValues(pvs, true);}catch (BeansException ex) {if (logger.isErrorEnabled()) {logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);}throw ex;}}// Let subclasses do whatever initialization they like.initServletBean();if (logger.isDebugEnabled()) {logger.debug("Servlet '" + getServletName() + "' configured successfully");}
}protected final void initServletBean() throws ServletException {getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'");if (this.logger.isInfoEnabled()) {this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started");}long startTime = System.currentTimeMillis();try {this.webApplicationContext = initWebApplicationContext();initFrameworkServlet();}catch (ServletException | RuntimeException ex) {this.logger.error("Context initialization failed", ex);throw ex;}if (this.logger.isInfoEnabled()) {long elapsedTime = System.currentTimeMillis() - startTime;this.logger.info("FrameworkServlet '" + getServletName() + "': initialization completed in " +elapsedTime + " ms");}
}protected WebApplicationContext initWebApplicationContext() {WebApplicationContext rootContext =WebApplicationContextUtils.getWebApplicationContext(getServletContext());WebApplicationContext wac = null;if (this.webApplicationContext != null) {// A context instance was injected at construction time -> use itwac = this.webApplicationContext;if (wac instanceof ConfigurableWebApplicationContext) {ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;if (!cwac.isActive()) {// The context has not yet been refreshed -> provide services such as// setting the parent context, setting the application context id, etcif (cwac.getParent() == null) {// The context instance was injected without an explicit parent -> set// the root application context (if any; may be null) as the parentcwac.setParent(rootContext);}configureAndRefreshWebApplicationContext(cwac);}}}if (wac == null) {// No context instance was injected at construction time -> see if one// has been registered in the servlet context. If one exists, it is assumed// that the parent context (if any) has already been set and that the// user has performed any initialization such as setting the context idwac = findWebApplicationContext();}if (wac == null) {// No context instance is defined for this servlet -> create a local onewac = createWebApplicationContext(rootContext);}if (!this.refreshEventReceived) {// Either the context is not a ConfigurableApplicationContext with refresh// support or the context injected at construction time had already been// refreshed -> trigger initial onRefresh manually here.onRefresh(wac);}if (this.publishContext) {// Publish the context as a servlet context attribute.String attrName = getServletContextAttributeName();getServletContext().setAttribute(attrName, wac);if (this.logger.isDebugEnabled()) {this.logger.debug("Published WebApplicationContext of servlet '" + getServletName() +"' as ServletContext attribute with name [" + attrName + "]");}}return wac;
}protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent) {Class<?> contextClass = getContextClass();if (this.logger.isDebugEnabled()) {this.logger.debug("Servlet with name '" + getServletName() +"' will try to create custom WebApplicationContext context of class '" +contextClass.getName() + "'" + ", using parent context [" + parent + "]");}if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {throw new ApplicationContextException("Fatal initialization error in servlet with name '" + getServletName() +"': custom WebApplicationContext class [" + contextClass.getName() +"] is not of type ConfigurableWebApplicationContext");}ConfigurableWebApplicationContext wac =(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);wac.setEnvironment(getEnvironment());wac.setParent(parent);String configLocation = getContextConfigLocation();if (configLocation != null) {wac.setConfigLocation(configLocation);}configureAndRefreshWebApplicationContext(wac);return wac;
}
创建完上下文后,在子类DispatcherServlet的onFresh中会调用initStrategies来初始化spring mvc框架。LocaleResolver用来支持国际化,HandlerMapping是请求到控制器之间的映射,ViewResolver用来视图生成。如果没有找到对应的bean,会使用默认的,在DispatcherServlet.properties中有配置默认的策略。
protected void initStrategies(ApplicationContext context) {initMultipartResolver(context);initLocaleResolver(context);initThemeResolver(context);initHandlerMappings(context);initHandlerAdapters(context);initHandlerExceptionResolvers(context);initRequestToViewNameTranslator(context);initViewResolvers(context);initFlashMapManager(context);
}
其类结构为
启动时序图为
DispatcherServlet的启动和初始化相关推荐
- 【Spring】DispatcherServlet的启动和初始化
使用过SpringMVC的都知道DispatcherServlet,下面介绍下该Servlet的启动与初始化.作为Servlet,DispatcherServlet的启动与Serlvet的启动过程是相 ...
- 启动未初始化小应用程序_SpringBoot详细打印启动时异常堆栈信息
1. 前言 随着我们项目的不断迭代 Bean 的数量会大大增加,如果都在启动时进行初始化会非常耗时.Spring Boot 允许延迟初始化应用程序, 也就是根据需要初始化 Spring Bean,而不 ...
- 如何在Mysql的Docker容器启动时初始化数据库
1.前言 Docker在开发中使用的越来越多了,最近搞了一个Spring Boot应用,为了方便部署将Mysql也放在Docker中运行.那么怎么初始化 SQL脚本以及数据呢? 我这里有两个传统方案. ...
- Quartz详解和使用CommandLineRunner在项目启动时初始化定时任务
文章目录 Quartz介绍 自定义CommandLineRunner类: 创建.更新定时任务 service层 自定义QuartzJobBean 智能调度组件 定时任务实体类: mapper接口: 时 ...
- Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源
Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源 在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等.今天就给大家介绍一个 Spri ...
- datanode无法启动_Hadoop DataNode启动和初始化过程
简介 我们先看DataNode的doc文档的介绍,DataNode是一个类,用于存储一组块,用于DFS部署.单个部署可以有一个或多个DataNode.每个DataNode通信定期与单个NameNode ...
- docker 容器启动顺序_Docker容器启动时初始化Mysql数据库
1. 前言 Docker在开发中使用的越来越多了,最近搞了一个Spring Boot应用,为了方便部署将Mysql也放在Docker中运行.那么怎么初始化 SQL脚本以及数据呢? 我这里有两个传统方案 ...
- docker mysql数据库初始化_如何在Mysql的Docker容器启动时初始化数据库
1.前言 Docker在开发中使用的越来越多了,最近搞了一个Spring Boot应用,为了方便部署将Mysql也放在Docker中运行.那么怎么初始化 SQL脚本以及数据呢? 我这里有两个传统方案. ...
- ServletContentLIstener接口演示ServletContext的启动和初始化
ServletContextListener接口中包含两个方法,一个是contextInitialized()方法, 用来监听ServletContext的启动和初始化:一个是contextDestr ...
最新文章
- SAP LSMW 物料主数据导入毛重净重放大1000倍问题之对策
- *Boosting*笔记
- BZOJ 3119 Book (贪心+数学推导)
- 用Socket编写TCP程序(C/C++)(转)
- id文本框适应文字_Indesign中对同一行文字进行分行缩排的操作方法
- python人工智能——机器学习——特征工程
- Adhesive框架系列文章--Mongodb数据服务使用实践
- 基于tensorflow2.0利用CNN与线性回归两种方法实现手写数字识别
- linux搭建flask环境,Ubuntu 环境下搭建Flask框架
- 老板怒了,“我们赚钱你们花钱,还总出毛病!”
- 收拾老家发现的老版纸币,现在还能用吗?
- 计算机硬件基础-笔记
- bzoj 2795	[Poi2012]A Horrible Poem hash+线性筛
- 常用的 Cron 时间表达式 定时器 正则表达式
- Exchange 2010 用户邮箱使用空间统计
- 人件札记:团队的化学反应
- 人群计数经典方法Density Map Estimation,密度图估计
- Nginx安装配置报错详解
- 计算机协会游园活动方案,大学计算机协会演讲比赛活动策划方案
- 如何在shell脚本中定义数组及遍历
热门文章
- Substring with Concatenation of All Words
- WPF-数据绑定:日期时间格式
- 前1000位粉丝的诞生
- python怎么读取txt文件并统计其字数-python计算文件的行数和读取某一行内容的实现方法...
- python3.6安装教程-Python 3.6.6安装教程(附安装包) | 我爱分享网
- python在线工具-在线 Python运行工具
- python新手教程 从零开始-Python零基础从零开始学习Python十分钟快速入门
- python有用吗-python有用么
- python程序设计报告-20192116 实验一《Python程序设计》实验报告
- python 爬虫实例 电影-Python爬虫教程-17-ajax爬取实例(豆瓣电影)