SpringBoot(六)之内嵌容器

SpringBoot(六)之内嵌容器

文章目录

    • SpringBoot(六)之内嵌容器
      • 内嵌容器的特点
      • 如何替换默认容器
        • 1.pom形式
        • 2.主动配置
      • 如何通过配置切换serlvet容器

Spring Boot 提供了一种便捷的方式来创建独立运行的 Spring 应用程序,内嵌容器(如 Tomcat、Jetty 或 Undertow)是其核心特性之一。这使得开发者不需要将应用程序部署到外部的应用服务器上,而是通过内嵌容器直接运行应用。这种方式简化了部署流程,并且提高了开发和测试的效率。

内嵌容器的特点

  1. 独立性:应用程序包含了所有必要的依赖和服务器配置,能够独立运行,而不依赖外部的应用服务器。
  2. 简化部署:通过 Maven 或 Gradle 构建后,可以生成一个可执行的 JAR 文件,直接通过命令行运行。
  3. 一致性:开发、测试和生产环境中的运行环境一致,减少了环境差异带来的问题。

如何替换默认容器

1.pom形式

如何引入underTow作为内嵌servlet容器

  • 在spring-boot-starter-web中排除掉tomcat的jar包
  • 引入undertow的依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><!-- 使用 Undertow 替换掉 Tomcat --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

观察console

2024-05-17 16:38:26.099  INFO 1108 --- [           main] io.undertow                              : starting server: Undertow - 2.2.16.Final
2024-05-17 16:38:26.102  INFO 1108 --- [           main] org.xnio                                 : XNIO version 3.8.6.Final
2024-05-17 16:38:26.105  INFO 1108 --- [           main] org.xnio.nio                             : XNIO NIO Implementation Version 3.8.6.Final
2024-05-17 16:38:26.125  INFO 1108 --- [           main] org.jboss.threads                        : JBoss Threads version 3.1.0.Final
2024-05-17 16:38:26.162  INFO 1108 --- [           main] o.s.b.w.e.undertow.UndertowWebServer     : Undertow started on port(s) 8080 (http)
2024-05-17 16:38:26.168  INFO 1108 --- [           main] c.a.s.SpringBootAnnotationApplication    : Started SpringBootAnnotationApplication in 1.179 seconds (JVM running for 1.914)

通过日志观察,默认内嵌容器已经替换成underTow,同理jetty一样

2.主动配置

由于SpringBoot在获取servlet容器是通过ServletWebServerFactory类型来获取。ServletWebServerFactory一共有三个实现类,分别为JettyServletWebServerFactory,UndertowServletWebServerFactory,TomcatServletWebServerFactory。分别对应jetty,underTow,tomcat。

SpringBoot在AbstractApplicationContext.refresh()方法的onRefresh(),通过 ServletWebServerApplicationContext重写该方法创建webServer();

protected void onRefresh() {super.onRefresh();try {this.createWebServer();} catch (Throwable var2) {throw new ApplicationContextException("Unable to start web server", var2);}
}

在createWebServer()中有个获取WebServerFactory方法获取对应的实现类的方法getWebServerFactory();

protected ServletWebServerFactory getWebServerFactory() {String[] beanNames = this.getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);if (beanNames.length == 0) {throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.");} else if (beanNames.length > 1) {throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));} else {return (ServletWebServerFactory)this.getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);}}

getWebServerFactory(),通过在Spring容器中获取ServletWebServerFactory类型的bean,如果获取不到和获取多个都会抛出异常

所以我们可以通过手动配置ServletWebServerFactory对应的实现类,以此来切换不同的容器。

  • 将tomcat,jetty,undertow的starter都引入到项目中
  • 新建配置ServletServerConfig
@Configuration
public class ServletServerConfig {@Beanpublic ServletWebServerFactory underTowServletWebServerFactory(){UndertowServletWebServerFactory undertowServletWebServerFactory = new UndertowServletWebServerFactory();undertowServletWebServerFactory.setPort(8087);return undertowServletWebServerFactory;}//@Beanpublic ServletWebServerFactory tomcatServletWebServerFactory(){TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory();tomcatServletWebServerFactory.setPort(8081);return tomcatServletWebServerFactory;}//@Beanpublic ServletWebServerFactory jettyServletWebServerFactory(){JettyServletWebServerFactory jettyServletWebServerFactory = new JettyServletWebServerFactory();jettyServletWebServerFactory.setPort(8086);return jettyServletWebServerFactory;}
}

需要用哪个容器,就把其他两个容器注释掉。(不能创建多个ServletWebServerFactory,在getWebServerFactory()中会抛异常

如何通过配置切换serlvet容器

在主动配置的基础上,可以通过对config进行改造

  1. 在application.yaml中配置servlet.server属性 ,具体1,2,3代表tomcat还是jetty由自己定义
  2. 利用SpringBoot注解@ConditionalOnProperty注解可以切换servlet容器
servlet:server: 2
@Configuration
public class ServletServerConfig {@Bean@ConditionalOnProperty(name = "servlet.server",havingValue = "1")public ServletWebServerFactory underTowServletWebServerFactory(){UndertowServletWebServerFactory undertowServletWebServerFactory = new UndertowServletWebServerFactory();undertowServletWebServerFactory.setPort(8087);return undertowServletWebServerFactory;}@Bean@ConditionalOnProperty(name = "servlet.server",havingValue = "2")public ServletWebServerFactory tomcatServletWebServerFactory(){TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory();tomcatServletWebServerFactory.setPort(8081);return tomcatServletWebServerFactory;}@Bean@ConditionalOnProperty(name = "servlet.server",havingValue = "3")public ServletWebServerFactory jettyServletWebServerFactory(){JettyServletWebServerFactory jettyServletWebServerFactory = new JettyServletWebServerFactory();jettyServletWebServerFactory.setPort(8086);return jettyServletWebServerFactory;}
}

ServletServerConfig中,1表示underTow,2表示tomdat,3,表示jetty。而application.yml中配置的2,则启动项目,观察console

2024-05-17 17:14:19.142  INFO 7500 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2024-05-17 17:14:19.148  INFO 7500 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]

将配置更改为3,再次启动,观察console

2024-05-17 17:15:01.473  INFO 5260 --- [           main] o.e.jetty.server.AbstractConnector       : Started ServerConnector@13579834{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2024-05-17 17:15:01.473  INFO 5260 --- [           main] o.s.b.web.embedded.jetty.JettyWebServer  : Jetty started on port(s) 8080 (http/1.1) with context path '/'

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

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

相关文章

计算机毕业设计hadoop+spark微博舆情大数据分析 微博爬虫可视化 微博数据分析 微博采集分析平台 机器学习(大屏+LSTM情感分析+爬虫)

电商数据建模 一、分析背景与目的 1.1 背景介绍 电商平台数据分析是最为典型的一个数据分析赛道&#xff0c;且电商数据分析有着比较成熟的数据分析模型&#xff0c;比如&#xff1a;人货场模型。此文中我将通过分析国内最大的电商平台——淘宝的用户行为&#xff0c;来巩固数…

算法打卡 Day13(栈与队列)-滑动窗口最大值 + 前 K 个高频元素 + 总结

文章目录 Leetcode 239-滑动窗口最大值题目描述解题思路 Leetcode 347-前 K 个高频元素题目描述解题思路 栈与队列总结 Leetcode 239-滑动窗口最大值 题目描述 https://leetcode.cn/problems/sliding-window-maximum/description/ 解题思路 在本题中我们使用自定义的单调队列…

C语言指针指针和数组笔试题(必看)

前言&#xff1a; 前面介绍了指针的大体内容&#xff0c;如果接下来能够把这些代码的含义搞得清清楚楚&#xff0c;那么你就是代码king&#xff01; 一维数组&#xff1a; int a[] {1,2,3,4}; printf("%d\n",sizeof(a)); printf("%d\n",sizeof(a0)); pr…

element-ui输入框和多行文字输入框字体不一样解决

element-ui的type"textarea"的字体样式与其他样式不同 <el-input type"textarea"></el-input> <el-input ></el-input>设置&#xff1a; .el-textarea__inner::placeholder {font-family: "Helvetica Neue", Helvetic…

linux排查思路

1.账号安全 who 查看当前登录用户&#xff08;tty本地登录pts远程登录&#xff09; w 查看系统信息&#xff0c;想知道某一时刻用户的行为 uptime 查看登录多久、多少用户&#xff0c;负载 1.查看用户信息文件/etc/passwd root:x:0:0:root:/root:/bin:/b…

删除MySQL中所有表的外键

方法一&#xff1a; 原理 查询schema中所有外键名称然后拼接生成删除语句 第一步&#xff1a; SELECT CONCAT(ALTER TABLE ,TABLE_SCHEMA,.,TABLE_NAME, DROP FOREIGN KEY ,CONSTRAINT_NAME, ;) FROM information_schema.TABLE_CONSTRAINTS c WHERE c.TABLE_SCHEMA数据库名…

Vue 跨域代理设置

Vue CLI允许你通过项目根目录下的vue.config.js文件来定制devServer的配置。以下是一些常见的配置示例&#xff1a; module.exports {devServer: {// 跨域代理配置&#xff0c;解决开发环境API跨域问题proxy: {//匹配以api路径请求的URL&#xff0c;转发请求的服务器地址/api…

课时135:awk实践_逻辑控制_综合实践

1.3.8 综合实践 学习目标 这一节&#xff0c;我们从 网络实践、文件实践、小结 三个方面来学习 网络实践 简介 所谓的网络实践&#xff0c;主要是借助于awk的数组功能&#xff0c;进行站点的信息统计操作。准备网络环境 安装软件 yum install nignx -y重启nginx [rootloca…

Linux修炼之路之自动化构建工具,进度条,gdb调试器

目录 一&#xff1a;自动化构建工具make/makefile 生成内容&#xff1a; 清理内容&#xff1a; 对于多过程的&#xff1a; 对于多次make&#xff1a; 特殊符号&#xff1a; 二&#xff1a;小程序之进度条 三&#xff1a;git的简单介绍 四&#xff1a;Linux调试器gdb 接…

fpga 提高有什么进阶书推荐?

到FPGA中后期的时候就要开始接触&#xff0c;如&#xff1a;高速接口、光纤数字信号处理等项目实践了&#xff0c;那么我们可以读一些书进行提升&#xff0c;大家可以收藏下。 高速接口项目《嵌入式高速串行总线技术:基于FPGA实现与应用》作者&#xff1a;张锋 FPGA提升书籍推…

Go团队:Go是什么

2024年的Google I/O大会[1]如期而至。 这届大会的核心主旨毫无疑问是坚定不移的以AI为中心&#xff1a;Google先是发布了上下文长度将达到惊人的200万token的Gemini 1.5 Pro[2]&#xff0c;然后面对OpenAI GPT-4o的挑衅&#xff0c;谷歌在大会上直接甩出大杀器Project Astra[3]…

第七节 ConfigurationClassParser 源码分析

tips&#xff1a; ConfigurationClassParser 是 Springframework 中的重要类。 本章主要是源码理解&#xff0c;有难度和深度&#xff0c;也枯燥乏味&#xff0c;可以根据实际情况选择阅读。 位置&#xff1a;org.springframework.context.annotation.ConfigurationClassPars…

[LLM-Agents]浅析Agent工具使用框架:MM-ReAct

上文LLM-Agents]详解Agent中工具使用Workflow提到MM-ReAct框架&#xff0c;通过结合ChatGPT 与视觉专家模型来解决复杂的视觉理解任务的框架。通过设计文本提示&#xff08;prompt design&#xff09;&#xff0c;使得语言模型能够接受、关联和处理多模态信息&#xff0c;如图像…

winform在一个类中调用窗体的控件和方法的两个方式

第一: 在类中创建窗体对象的方式&#xff0c;通过对象调用控件或方法 eg: Form1 form1 new Form1(); form1.Button; //调用控件 form1.Method(); //调用方法 要注意&#xff0c;对应控件的Modifiers属性要设置成public . 第二: 在窗体Form类下定义静态变量(例如:form1)&…

Multi-Attention Transformer for Naturalistic Driving Action Recognition

标题&#xff1a;用于自然驾驶行为识别的多注意力Transformer 源文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2023W/AICity/papers/Dong_Multi-Attention_Transformer_for_Naturalistic_Driving_Action_Recognition_CVPRW_2023_paper.pdfhttps://openaccess…

linux创建私有docker仓库以及推拉

创建私有仓库&#xff1a; 1.下载 registry镜像。 2.执行 registry 镜像&#xff08;#为注释内容&#xff0c;\为换行&#xff09;&#xff1a; docker run -d \# --restartalways每次都是开机自动启动--restartalways \# --name registry 表示容器名--name registry \# 表示…

java读取shp文件,获取点位

Testvoid contextLoads() {System.out.println(System.currentTimeMillis());//1716516228057 1716516228798String zipFilePath "C:\\code\\risk\\risk_management_backend\\edatope-app\\src\\main\\resources\\新中心范围SHP导入模板.zip";String destDir &quo…

【Muduo】TcpServer类

TcpServer统领之前所有的类&#xff0c;是用户直接使用的类。它通过ThreadPool管理所有的loopthread&#xff0c;保存所有的TcpConnection&#xff0c;保存用户提供的各种回调函数并向TcpConnection的Channel中注册回调。它负责监听指定的端口&#xff0c;并接受来自客户端的连…

ZeRO-3、模型并行、流水线并行适用情况

ZeRO-3 适用场景&#xff1a;参数量大但计算量相对均衡的情况。 主要特点&#xff1a; 参数分片&#xff1a;将模型参数、优化器状态和梯度在多个 GPU 上进行分片。显存优化&#xff1a;显著减少每个 GPU 上的显存占用&#xff0c;使得可以在较小的 GPU 上训练更大的模型。 …