从头看看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定义:把对象的创 ...
随机推荐
- 小程序的优化代码的分析Promise方法
代码优化,这里通过了wx.request请求轮播图的API,通过result结果里面的data数据我们可以看到massage里面装着我们的数据 通过图片可以用看到swiperList返回的三个元素的数 ...
- 浅谈python深复制与浅复制区别
话不多说,看代码
- IOS 单例崩溃分析 2014-12-10 15:46:36
单例模式是常用的模式,但是在单例应用中偶或引发崩溃让人匪夷所思.其实真的是单例引起的吗?未必.但是现象都指向了是单例引起的.今天我亲身经历了看似崩溃在单例上的一个例子,但实则不是,今天做个记录用于今后 ...
- 基于Prometheus和Grafana打造业务监控看板
前言 业务监控对许许多多的场景都是十分有意义,业务监控看板可以让我们比较直观的看到当前业务的实时情况,然后运营人员可以根据这些情况及时对业务进行调整操作,避免业务出现大问题. 老黄曾经遇到过一次比较尴 ...
- 【支付宝SDK】沙箱调试,以及遇到的坑
from rest_framework.views import APIView from alipay import AliPay, DCAliPay, ISVAliPay from django. ...
- 在.NET Core中使用MongoDB明细教程(3):Skip, Sort, Limit, Projections
到目前为止,我们已经讨论了创建文档, 检索文档,现在让我们来研究一下文档排序,指定要跳过或限制返回的文档数量,以及如何进行投影.此篇文章中的实例代码摘录自原文,未像前几篇文章一样进行实际代码的验证. ...
- Spring @Transactional事物配置无效原因
spring @transaction不起作用,Spring事物注意事项 1. 在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方 ...
- 二叉搜索树及java实现
二叉搜索树(Binary Search Tree) 二叉搜索树是二叉树的一种,是应用非常广泛的一种二叉树,英文简称为 BST 又被称为:二叉查找树.二叉排序树 任意一个节点的值都大于其左子树所有节 ...
- Python之运维
这几日一直研究运维监控的事情,有次看见有一个脚本写的还不错,如今已经找不到地址了 就只能用Python代替shell了 其中原理是 监控 /proc/下的各种文件,/proc/ 顾名思义其为进程的文件 ...
- CodeQL CLI入门
一.CodeQL CLI 安装和配置 1.下载CodeQL CLI 压缩包 https://github.com/github/codeql-cli-binaries/releases 2.创建Cod ...

