从头看看Tomcat启动Spring容器的原理
通过带注解Spring Boot可以启动一个web容器,并初始化bean容器。那么Tomcat启动并初始化spring容器的原理是怎样的?
Tomcat启动web程序时会创建一对父子容器(图1):
有几种方式:
- XML配置Spring和Servlet容器
- 通过注解初始化
- Servlet提供SPI的调用方式来启动
XML配置Spring和Servlet容器
web.xml主要通过一下配置初始化父子容器(父子容器是职责单一的设计)
<web-app>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> <!-- 初始化父容器-->
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 初始化子容器-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Listener主要作用就是初始化spring的bean容器,servlet做request的转发
<listener>
==> @WebListerner
<Servlet> ==> @WebServlet
<Filter> ==> @WebFilter Servlet提供SPI的调用方式来启动
打开service文件有一行如下:
org.springframework.web.SpringServletContainerInitializer 就是给Tomcat提供初始化容器用的服务接口,Tomcat启动的时候就会通过ServiceLoader把这个类加载进来,然后调用该类的onStartUp方法来初始化
@HandlesTypes({WebApplicationInitializer.class})
public class SpringServletContainerInitializer implements ServletContainerInitializer {
注解中的WebApplicationInitializer.clas就是引入的容器初始化类了。
看一下他的子类:
public abstract class SpringBootServletInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
this.logger = LogFactory.getLog(this.getClass());
WebApplicationContext rootApplicationContext = this.createRootApplicationContext(servletContext);
if (rootApplicationContext != null) {
servletContext.addListener(new SpringBootServletInitializer.SpringBootContextLoaderListener(rootApplicationContext, servletContext));
} else {
this.logger.debug("No ContextLoaderListener registered, as createRootApplicationContext() did not return an application context");
} }
}
其中的onStartup方法中有addListener,这个添加的Listener正是对应的XML中:<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
其中的SpringBootContextLoaderListener是该类的内部类,继承自ContextLoaderListener
其中的this.createRootApplicationContext(servletContext);便是创建图1中的父容器
从头看看Tomcat启动Spring容器的原理的更多相关文章
- spring容器IOC原理解析
原理简单介绍: Spring容器的原理,其实就是通过解析xml文件,或取到用户配置的bean,然后通过反射将这些bean挨个放到集合中,然后对外提供一个getBean()方法,以便我们获得这些bean ...
- 8 -- 深入使用Spring -- 7...1 启动Spring 容器
8.7.1 启动Spring容器 对于使用Spring的Web应用,无须手动创建Spring容器,而是通过配置文件声明式地创建Spring容器.因此,在Web应用中创建Spring容器有如下两种方式: ...
- 基于反射启动Spring容器
基于反射启动Spring容器 package com.maple.test; import org.springframework.context.ApplicationContext; import ...
- tomcat 启动Spring boot 项目
SpringBoot 项目如何在tomcat容器中运行 1.相关连接: https://blog.csdn.net/u010598360/article/details/78789197/ 2.修改打 ...
- springMVC项目部署 服务器启动spring容器报错bean未从类加载器中找到
bean未从类加载器中找到 警告: Exception encountered during context initialization - cancelling refresh attempt: ...
- spring容器启动
1 主要类 ContextLoaderListener:注册在web.xml中,web应用启动时,会创建它,并回调它的initWebApplicationContext()方法,从而创建并启动spri ...
- spring容器启动的三种方式
一.在Web项目中,启动Spring容器的方式有三种,ContextLoaderListener.ContextLoadServlet.ContextLoaderPlugin. 1.1.监听器方式: ...
- ServletContext与Web应用以及Spring容器启动
一.ServletContext对象获取Demo Servlet容器在启动时会加载Web应用,并为每个Web应用创建唯一的ServletContext对象. 可以把ServletContext看作一个 ...
- spring容器IOC创建对象<二>
问题?spring是如何创建对象的?什么时候创建对象?有几种创建方式?测试对象是单例的还是多例的 ?对象的初始化和销毁? 下面的四大模块IOC的内容了!需要深刻理解 SpringIOC定义:把对象的创 ...
随机推荐
- Homekit_Dohome_智能插座
简介: 本款智能插座有三个版本可供选择,分别为Homekit版本,涂鸦版本,Dohome版本,各个版本的区别如下: DoHome版特点: 支持HomeKit 支持Amazon 支持Google ...
- 设计模式:原型模式介绍 && 原型模式的深拷贝问题
0.背景 克隆羊问题:有一个羊,是一个类,有对应的属性,要求创建完全一样的10只羊出来. 那么实现起来很简单,我们先写出羊的类: public class Sheep { private String ...
- 分享一个Flink checkpoint失败的问题和解决办法
本文来自: PerfMa技术社区 PerfMa(笨马网络)官网 接触Flink一段时间了,遇到了一些问题,其中有一个checkpoint失败导致作业重启的问题,遇到了很多次,重启之后一般也能恢复正常, ...
- Eclipse怎么切换工作空间
1.进行点击Eclipse编辑代码的窗口界面中,进行点击菜单中file的选项. 2.弹出了下拉菜单中进行选择为“switch workspace”的选项. 3.弹出了下一级菜单中进行选择为other的 ...
- 性能分析(7)- 未利用系统缓存导致 I/O 缓慢案例
性能分析小案例系列,可以通过下面链接查看哦 https://www.cnblogs.com/poloyy/category/1814570.html 前提 前面有学到 Buffer 和 Cache 的 ...
- 关于MapReduce默认分区策略
MapReduce默认分区策略 mapreduce 默认的分区方式是hashPartition,在这种分区方式下,KV对根据key的hashcode值与reduceTask个数进行取模,决定该键值对该 ...
- 解决VS Code安装golang相关插件失败问题
解决VS Code安装golang相关插件失败问题 VSCode作为一款优秀的编辑器,基本上前端开发,Python,markdown都可以用,真正是开发过程中的好帮手,所以学习go也当仁不让的要用vs ...
- CSP-J2019 NOIP普及组初赛真题(阅读程序部分)
阅读程序(程序输入不超过数组或字符串定义的范围:判断题正确填√,错误填×:除特殊说明外,判断题1.5分,选择题3分,共计40分) #include <cstdio> #include &l ...
- linux命令查询网站
http://linux.51yip.com/ http://man.linuxde.net/ Linux命令查询手册Linux终端下 esc + . 可以获取上次文件名
- mycli工具mysql命令自动补全
简介 MyCli 是一个 MySQL 的命令行客户端,可以实现自动补全和语法高亮.MyCli 也可用于 MariaDB 和Percona. 项目地址:http://mycli.net/ 安装 pip安 ...