通过带注解Spring Boot可以启动一个web容器,并初始化bean容器。那么Tomcat启动并初始化spring容器的原理是怎样的?

Tomcat启动web程序时会创建一对父子容器(图1):

有几种方式:

  1. XML配置Spring和Servlet容器
  2. 通过注解初始化
  3. 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容器的原理的更多相关文章

  1. spring容器IOC原理解析

    原理简单介绍: Spring容器的原理,其实就是通过解析xml文件,或取到用户配置的bean,然后通过反射将这些bean挨个放到集合中,然后对外提供一个getBean()方法,以便我们获得这些bean ...

  2. 8 -- 深入使用Spring -- 7...1 启动Spring 容器

    8.7.1 启动Spring容器 对于使用Spring的Web应用,无须手动创建Spring容器,而是通过配置文件声明式地创建Spring容器.因此,在Web应用中创建Spring容器有如下两种方式: ...

  3. 基于反射启动Spring容器

    基于反射启动Spring容器 package com.maple.test; import org.springframework.context.ApplicationContext; import ...

  4. tomcat 启动Spring boot 项目

    SpringBoot 项目如何在tomcat容器中运行 1.相关连接: https://blog.csdn.net/u010598360/article/details/78789197/ 2.修改打 ...

  5. springMVC项目部署 服务器启动spring容器报错bean未从类加载器中找到

    bean未从类加载器中找到 警告: Exception encountered during context initialization - cancelling refresh attempt: ...

  6. spring容器启动

    1 主要类 ContextLoaderListener:注册在web.xml中,web应用启动时,会创建它,并回调它的initWebApplicationContext()方法,从而创建并启动spri ...

  7. spring容器启动的三种方式

    一.在Web项目中,启动Spring容器的方式有三种,ContextLoaderListener.ContextLoadServlet.ContextLoaderPlugin. 1.1.监听器方式: ...

  8. ServletContext与Web应用以及Spring容器启动

    一.ServletContext对象获取Demo Servlet容器在启动时会加载Web应用,并为每个Web应用创建唯一的ServletContext对象. 可以把ServletContext看作一个 ...

  9. spring容器IOC创建对象<二>

    问题?spring是如何创建对象的?什么时候创建对象?有几种创建方式?测试对象是单例的还是多例的 ?对象的初始化和销毁? 下面的四大模块IOC的内容了!需要深刻理解 SpringIOC定义:把对象的创 ...

随机推荐

  1. 小程序的优化代码的分析Promise方法

    代码优化,这里通过了wx.request请求轮播图的API,通过result结果里面的data数据我们可以看到massage里面装着我们的数据 通过图片可以用看到swiperList返回的三个元素的数 ...

  2. 浅谈python深复制与浅复制区别

    话不多说,看代码

  3. IOS 单例崩溃分析 2014-12-10 15:46:36

    单例模式是常用的模式,但是在单例应用中偶或引发崩溃让人匪夷所思.其实真的是单例引起的吗?未必.但是现象都指向了是单例引起的.今天我亲身经历了看似崩溃在单例上的一个例子,但实则不是,今天做个记录用于今后 ...

  4. 基于Prometheus和Grafana打造业务监控看板

    前言 业务监控对许许多多的场景都是十分有意义,业务监控看板可以让我们比较直观的看到当前业务的实时情况,然后运营人员可以根据这些情况及时对业务进行调整操作,避免业务出现大问题. 老黄曾经遇到过一次比较尴 ...

  5. 【支付宝SDK】沙箱调试,以及遇到的坑

    from rest_framework.views import APIView from alipay import AliPay, DCAliPay, ISVAliPay from django. ...

  6. 在.NET Core中使用MongoDB明细教程(3):Skip, Sort, Limit, Projections

    到目前为止,我们已经讨论了创建文档, 检索文档,现在让我们来研究一下文档排序,指定要跳过或限制返回的文档数量,以及如何进行投影.此篇文章中的实例代码摘录自原文,未像前几篇文章一样进行实际代码的验证. ...

  7. Spring @Transactional事物配置无效原因

    spring @transaction不起作用,Spring事物注意事项 1. 在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方 ...

  8. 二叉搜索树及java实现

    二叉搜索树(Binary Search Tree) 二叉搜索树是二叉树的一种,是应用非常广泛的一种二叉树,英文简称为 BST 又被称为:二叉查找树.二叉排序树 任意一个节点的值都大于其左子树所有节 ...

  9. Python之运维

    这几日一直研究运维监控的事情,有次看见有一个脚本写的还不错,如今已经找不到地址了 就只能用Python代替shell了 其中原理是 监控 /proc/下的各种文件,/proc/ 顾名思义其为进程的文件 ...

  10. CodeQL CLI入门

    一.CodeQL CLI 安装和配置 1.下载CodeQL CLI 压缩包 https://github.com/github/codeql-cli-binaries/releases 2.创建Cod ...