spring5源码篇(13)——spring mvc无xml整合tomcat与父子容器的启动

spring-framework 版本:v5.3.19

文章目录

  • 整合步骤
  • 实现原理
    • ServletContainerInitializer与WebApplicationInitializer
    • 父容器的启动
    • 子容器的启动
  • 相关面试题

整合步骤

试想这么一个场景。只用 spring mvc(确切来说是spring-framework), 如何既不搭建web工程(无web.xml)又不用 spring boot 的去整合tomcat部署一个web服务?

1、引入 tomcat 和 spring mvc

   		......<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.9</version></dependency><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><version>9.0.62</version></dependency>......

2、实现 WebApplicationInitializer接口,即本篇实现的spring mvc 提供的 AbstractAnnotationConfigDispatcherServletInitializer 类
在这里插入图片描述
3、编写controller类
在这里插入图片描述
4、编写main函数启动 tomcat
在这里插入图片描述
验证:
在这里插入图片描述

整个项目目录如下
在这里插入图片描述

案例 github 地址:https://github.com/no-shutdown/springmvcandjsp.git

实现原理

ServletContainerInitializer与WebApplicationInitializer

ServletContainerInitializer是Java Servlet 3.0规范中的一部分,接口定义了一个onStartup方法,容器(例如Tomcat、Jetty等)在启动Web应用程序时会调用这个方法。

至于容器如tomcat里的代码是如何得到用户自定义的接口实现类的?
答:通过SPI的方式去获取。

SpringServletContainerInitializer
spring中为我们实现的ServletContainerInitializer实现类如下
在这里插入图片描述

@HandlesTypes 是Java Servlet 3.0规范中ServletContainerInitializer接口的一个特性,用于向ServletContainerInitializer提供在类路径上发现的类的信息。比如:这里的意思就是说,会收集路径上所有的 WebApplicationInitializer 类作为方法参数传入。

所以也就是说,在本篇的案例中,main函数启动tomcat时,tomcat会通过SPI的方式去调用到 SpringServletContainerInitializer 类的onStartup方法,而 SpringServletContainerInitializer 又会通过 @HandlesTypes 获取到所有 WebApplicationInitializer 类并调用他们的 onStartup 方法。

所以其实并不一定要继承 AbstractAnnotationConfigDispatcherServletInitializer ,也可以自己去实现一个 WebApplicationInitializer 接口,总之需要在 WebApplicationInitializer#onStratUp 中去启动父子容器。

AbstractAnnotationConfigDispatcherServletInitializer
AbstractAnnotationConfigDispatcherServletInitializer 就是 spring mvc 为我们提供的 WebApplicationInitializer 接口抽象类中的其中一个。其 onStartup 方法做了一些启动父子容器相关的操作。
在这里插入图片描述

父容器的启动

registerContextLoaderListener
在这里插入图片描述
这个方法做了两件事
1:创建一个spring容器
2:注册 ContextLoaderListener 到servlet容器

创建父容器的代码上图中一起给了,这里再看下 ContextLoaderListener 。
在这里插入图片描述
这是一个 ServletContextListener 监听类,在servlet容器启动时,会调用当前servlet容器所注册监听器的 contextInitialized 方法。

父容器就是在 ContextLoaderListener.contextInitialized 中启动的,如下
在这里插入图片描述

子容器的启动

registerDispatcherServlet
在这里插入图片描述
这个方法做了两件事
1:创建一个spring容器
2:注册 DispatcherServlet 到servlet容器

创建子容器的代码上图中一起给了,这里再看下 DispatcherServlet 。
在这里插入图片描述
这个类并不陌生,就是 spring mvc 的前端控制器。
但从servlet容器的角度来看,就是一个普通的HttpServlet,所以必然遵循servlet生命周期。
这个servlet生命周期的 init 方法就会去启动子容器。
在这里插入图片描述

相关面试题

1、spring和spring mvc为什么要设计父子容器?
答:单一职责原则,早期spring mvc并不是唯一的主流web框架。为方便快速拔插,比如从 spring mvc 切换到 struts,使用父子容器只需将spring­mvc.xml替换成struts的配置文件struts.xml即可,而spring­core.xml不需要改变。

2、是否可以把所有Bean都交给spring容器(父容器)来管理?
答:不可以,会出现404。因为 spring mvc 在启动时只会扫描当前容器下Controller注册HandlerMethod,并没有同时去查找父容器的bean。

3、是否可以把所有bean都交给spring mvc容器(子容器)来管理?
答:可以 , 因为父容器无非就是包含一些子容器不包含的bean, 如果全在子容器就完全不用父容器了。不过需要注意的是,如果bean都注册到子容器,原本在父容器配置事务、aop等也需要移动到子容器,否则是不会生效的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/12938.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flink集群运行模式--Standalone运行模式

Flink集群运行模式--Standalone运行模式 一、实验目的二、实验内容三、实验原理四、实验环境五、实验步骤5.1 部署模式5.1.1 会话模式&#xff08;Session Mode&#xff09;5.1.2 单作业模式&#xff08;Per-Job Mode&#xff09;5.1.3 应用模式&#xff08;Application Mode&a…

从头开始:数据结构和算法入门(时间复杂度、空间复杂度)

目录 文章目录 前言 1.算法效率 1.1 如何衡量一个算法的好坏 1.2 算法的复杂度 2.时间复杂度 2.1 时间复杂度的概念 2.2 大O的渐进表示法 2.3常见时间复杂度计算 3.空间复杂度 4.常见复杂度对比 总结 前言 C语言的学习篇已经结束&#xff0c;今天开启新的篇章——数据结构和算…

gitee 配置ssh 公钥(私钥)

步骤1&#xff1a;添加/生成SSH公钥&#xff0c;码云提供了基于SSH协议的Git服务&#xff0c;在使用SSH协议访问项目仓库之前&#xff0c;需要先配置好账户/项目的SSH公钥。 绑定账户邮箱&#xff1a; git config --global user.name "Your Name" git config --glob…

【图像去噪】基于进化算法——自组织迁移算法(SOMA)的图像去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

HTML基础知识点总结

目录 1.HTML简介 2.HTML基础结构 主要字符&#xff1a; 3.基础知识 &#xff08;一&#xff09;p标签 &#xff08;二&#xff09;hr标签 &#xff08;三&#xff09;尖角号 &#xff08;四&#xff09;版权号 (五)div和span div span (六)列表 &#xff08;1&…

【Docker】Docker相关基础命令

目录 一、Docker服务相关命令 1、启动docker服务 2、停止docker服务 3、重启docker服务 4、查看docker服务状态 5、开机自启动docker服务 二、Images镜像相关命令 1、查看镜像 2、拉取镜像 3、搜索镜像 4、删除镜像 三、Container容器相关命令 1、创建容器 2、查…

pytorch实现梯度下降算法例子

如题&#xff0c;利用pytorch&#xff0c;通过代码实现机器学习中的梯度下降算法&#xff0c;求解如下方程&#xff1a; f ′ ( x , y ) x 2 20 y 2 {f}(x,y) x^2 20 y^2 f′(x,y)x220y2 的最小值。 Latex语法参考&#xff1a;https://blog.csdn.net/ViatorSun/article/d…

RabbitMQ 集群部署

RabbiMQ 是用 Erlang 开发的,集群非常方便,因为 Erlang 天生就是一门分布式语言,但其本身并不支持负载均衡。 RabbitMQ 的集群节点包括内存节点、磁盘节点。RabbitMQ 支持消息的持久化,也就是数据写在磁盘上,最合适的方案就是既有内存节点,又有磁盘节点。 RabbitMQ 模式大…

【动态规划part12】| 309.买卖股票的最佳时机含冷冻期、714.买卖股票的最佳时机含手续费

目录 &#x1f388;LeetCode309.最佳买卖股票时机含冷冻期 &#x1f388;LeetCode714.买卖股票的最佳时机含手续费 &#x1f388;LeetCode309.最佳买卖股票时机含冷冻期 给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计…

Jenkins从配置到实战(二) - Jenkins的Master-Slave分布式构建

前言 Jenkins的Master-Slave分布式构建&#xff0c;就是通过将构建过程分配到从属Slave节点上&#xff0c;从而减轻Master节点的压力&#xff0c;而且可以同时构建多个&#xff0c;有点类似负载均衡的概念。简单理解就是&#xff0c;将Jenkins服务器上的构建任务分配到其他机器…

【Spring Boot】实战:实现优雅的数据返回

实战&#xff1a;实现优雅的数据返回 本节介绍如何让前后台优雅地进行数据交互&#xff0c;正常的数据如何统一数据格式&#xff0c;以及异常情况如何统一处理并返回统一格式的数据。 1.为什么要统一返回值 在项目开发过程中经常会涉及服务端、客户端接口数据传输或前后台分…

多分类问题-Softmax Classifier分类器

概率分布&#xff1a;属于每一个类别的概率总和为0&#xff0c;且都>0&#xff0c;n组类别需要n-1个参数就能算出结果 数据预处理 loss函数 crossentropyloss()函数 CrossEntropyLoss <> LogSoftmax NLLLoss。也就是说使用CrossEntropyLoss最后一层(线性层)是不需要做…

Fiddler Everywhere(TTP调试抓包工具) for Mac苹果电脑版

Fiddler Everywhere for Mac版是Mac电脑上的一款跨平台的HTTP调试抓包工具&#xff0c;Fiddler Everywhere for Mac能够记录客户端与服务器之间的所有HTTP&#xff08;S&#xff09;通信&#xff0c;支持对包进行监视、分析、设置断点、甚至修改请求/响应数据等操作。 适用于任…

基于量子同态加密的安全多方凸包协议

摘要安全多方计算几何(SMCG)是安全多方计算的一个分支。该协议是为SMCG中安全的多方凸包计算而设计的。首先&#xff0c;提出了一种基于量子同态加密的安全双方值比较协议。由于量子同态加密的性质&#xff0c;该协议可以很好地保护量子电路执行过程中数据的安全性和各方之间的…

【广州华锐互动】AR智慧机房设备巡检系统

AR智慧机房设备巡检系统是一种新型的机房巡检方式&#xff0c;它通过使用增强现实技术将机房设备、环境等信息实时呈现在用户面前&#xff0c;让巡检人员可以更加高效地完成巡检任务。 首先&#xff0c;AR智慧机房设备巡检系统具有极高的智能化程度。该系统可以根据用户设定的…

WIZnet W5500-EVB-Pico树莓派入门教程(一)

概述 W5500-EVB-Pico是基于树莓派RP2040和完全硬连线TCP/IP控制器W5500的微控制器开发板-基本上与树莓派Pico板相同&#xff0c;但通过W5500芯片增加了以太网功能。 板载资源 RP2040是Raspberry Pi的首款微控制器。它将我们的高性能、低成本和易用性的标志性价值观带入微控制器…

抖音短视频seo源码矩阵系统开发

一、前言&#xff1a; 抖音SEO源码矩阵系统开发是一项专为抖音平台设计的SEO优化系统&#xff0c;能够帮助用户提升抖音视频的搜索排名和曝光度。为了确保系统运行正常&#xff0c;需要安装FFmpeg和FFprobe工具。FFmpeg是一个用于处理多媒体数据的开源工具集&#xff0c;而FFpr…

Redis三种模式——主从复制,哨兵模式,集群

目录 一、主从复制 1.1主从复制的概念 1.2Redis主从复制作用 1.2.1数据冗余 1.2.2故障恢复 1.2.3负载均衡 1.2.4高可用基石 1.3Redis主从复制流程 1.4部署Redis 主从复制 1.4.1.环境部署 1.4.2.所有服务器都先关闭防火墙 1.4.3.所有服务器都安装Redis 1.4.4修改Master主节点R…

在CSDN学Golang云原生(Kubernetes声明式资源管理Kustomize)

一&#xff0c;生成资源 在 Kubernetes 中&#xff0c;我们可以通过 YAML 或 JSON 文件来定义和创建各种资源对象&#xff0c;例如 Pod、Service、Deployment 等。下面是一个简单的 YAML 文件示例&#xff0c;用于创建一个 Nginx Pod&#xff1a; apiVersion: v1 kind: Pod m…

Linux下CMake开发

CMake编译和运行C文件 编写CMakeLists.txt # 声明要求的 cmake 最低版本 cmake_minimum_required( VERSION 3.1 )# 声明一个 cmake 工程 project( pro )# 设置编译模式 set( CMAKE_BUILD_TYPE "Release" )#添加OPENCV库 #指定OpenCV版本&#xff0c;代码如下 #find…