Spring Boot为什么不需要额外安装Tomcat?

首次接触 Spring Boot 的时候,绝大多数小伙伴应该和我一样好奇:

为什么 Spring Boot 不需要额外安装 Tomcat 啊?

到底为什么呢?让我们带着好奇心开始今天的旅程吧。

打开上一节我们搭建好的 tobebetterjavaer 项目,找到 pom.xml 文件,可以在里面看到一个 parent 属性,代码如下:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.1</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

什么意思呢?

意思是我们当前的 Spring Boot 项目依赖于 spring-boot-starter-parent 这个父项目。有点 Java 中的继承(extends)的味道。

怎么查看 spring-boot-starter-parent.pom 文件的内容呢?

如果你不确定自己的 Maven 本地仓库在哪里,可以在终端执行 mvn help:effective-settings 命令。

顺藤摸瓜,根据 parent 的 groupId、artifactId、version 可以锁定 spring-boot-starter-parent.pom 文件的位置。

使用文本编辑器打开以后大致可以看到以下内容:

定义了 JDK 的版本为 1.8

项目默认的编码方式为 UTF-8

Maven 的编译环境

以及父依赖 spring-boot-dependencies

照葫芦画瓢,我们按照同样的方法找到 spring-boot-dependencies.pom 文件。可以看到这里面定义了一系列的属性和依赖,差不多 2800 行。

有消息队列依赖、commons 工具包依赖、数据库链接依赖、HTTP 链接依赖、Spring 家族依赖、Web 服务器依赖等等。

可以说这里是 Spring Boot 项目依赖的版本管理中心。

版本管理中心默认配置了项目所需的所有基础环境的版本,这些版本会随着 Spring Boot 版本的升级而不断变化,也就是说,开发人员不需要再关心这些琐碎依赖的版本了,交给大管家 Spring Boot 就可以了。

Spring Boot 会帮我们选好最稳定的新版本,这体现出了 Spring Boot 项目的灵魂:“约定优于配置”,你想配置当然可以,但没必要,按照约定俗成的来就行。

理解了这一点,我们再来继续看 pom.xml 文件,里面有一个 spring-boot-starter-web 依赖。这一次,我们直接按住 Ctrl 键(macOS 是 Command 键),点击鼠标左键就可以跳转到 spring-boot-starter-web.pom 的源文件了。

部分源码如下:

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.6.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-json</artifactId>
      <version>2.6.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <version>2.6.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.3.13</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.13</version>
      <scope>compile</scope>
    </dependency>

spring-web 提供了核心 HTTP 集成,包括一些便捷的 servlet 过滤器, Spring HTTP 调用,用于集成其它 web 框架的基础结构以及技术(Hessian,Burlap)。

spring-webmvc 是 Spring MVC 的一个实现。spring-webmvc 依赖于 spring-web,这样包含它就会间接地添加 spring-web,不必显示添加 spring-web。

看一下 spring-boot-starter-tomcat 的 pom 文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-tomcat</artifactId>
  <version>2.6.1</version>
  <name>spring-boot-starter-tomcat</name>
  <dependencies>
    <dependency>
      <groupId>jakarta.annotation</groupId>
      <artifactId>jakarta.annotation-api</artifactId>
      <version>1.3.5</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-core</artifactId>
      <version>9.0.55</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>tomcat-annotations-api</artifactId>
          <groupId>org.apache.tomcat</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-el</artifactId>
      <version>9.0.55</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-websocket</artifactId>
      <version>9.0.55</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>tomcat-annotations-api</artifactId>
          <groupId>org.apache.tomcat</groupId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>
</project>

从这里可以看出来SpringBoot默认的启动容器是Tomcat,Tomcat 的组成核心 jakarta.annotation、tomcat-embed-core、tomcat-annotations-api、org.apache.tomcat.embed 全部都通过 Maven 引入过来了。

core 的版本是 9.0.55,Tomcat 官网上最新的 9.0.x 版本是 9.0.56,高了一个版本。

不过无所谓,直接下载 9.0.56 的 src,对比看一下,是否大致相同

对比之下可以看得出,Spring Boot 引入的 Tomcat 更精简一点,大体上都是相同的,这也就是为什么Spring Boot 不需要额外安装 Tomcat 的根本原因了。

Spring Boot 的 starter 已经帮我们搞定过了。这也是Spring Boot 大行其道的重要原因,省去了开发人员配置的时间,更专注于业务逻辑的实现、性能的优化,至于那些繁杂的配置嘛,交给 Spring Boot 这个大管家就可以了,他约定好的东西,只要没问题,不需要特殊化定制,用就对了。


原出处:CSDN
原作者:「沉默王二」
#Java学习##学习路径#
全部评论

相关推荐

04-26 18:00
已编辑
门头沟学院 Java
AI辅助学习,用啥AI辅助学习?AI辅助学习出现了啥问题?一条Http的输入到输出流程什么是CDN说一下集群下怎么统一管理用户的Session状态JWT+Localstorage,Redis统一管理状态为什么要用Redis统一管理JWT?我直接客户端存一个UUID,然后Redis存用key-value,key是UUID,Value是用户信息不就行了?为什么一定要JWT?(牛mode,我能本地ThreadLocal解析出用户信息我还要用ThreadLocal存用户信息然后去Redis拿?)可能面试官是用Session的还是不懂JWT,一直盯着我的JWT喷final,Byte【】反射,属性不可变多线程去对i进行++操作他是少加还是漏加?可以用原子类来解决也就是安全计数器,底层被Synchronized修饰了Redisson,分布式锁AOP,AOP失效场景,如何解决AOP失效场景,详细的失效场景,事务的嵌套调用线程池的意义,为什么说创建线程会有开销,具体是什么开销。我都说到CPU共享时间片了,降低效率,浪费时间片轮转的时间线程池执行流程,拒绝策略,一般用什么拒绝策略? 如果线程池的队列满了并且到了最大线程数该怎么办?从这里开始他莫名其妙转牛角尖压力我了自定义拒绝策略+Mysql+定时任务兜底,利用Kafka的持久化机制防止消息丢失他说我说的不对?我说你实在不想队列满,你就弄个LinkedQueue无界队列,理论上就不会满了,也可以用Kafka理论上是无限大的从这开始他就莫名其妙说我了,你先别说Kafka你先说回前面的《理论上不会满那实际不会满吗?》我说实际如果太多会OOM,如果你想防止OOM可以用Kafka,Kafka理论上是无限大的《又是理论上吗》我说LinkedQueue最大长度10的九次方,理论上怎么可能会满?他说现在就有一个业务有10的九次方个任务呢?从这开始就不知道他的目的是问啥了,因为消息丢失,队列转型我都答了我不知道他让我回答一个业务有10的九次方个任务呢是干嘛a,b,c联合索引索引分类,模糊匹配,ES,倒排索引方法幂等性(这个我蠢了忘了setIfAbsent是原子性的)我就答了上锁固定时间,让ml的历史报文丢失布隆过滤器(马丁最蠢的一个东西),你为什么要这样设计呢?那我要是商标注册就是要准确找到是否存在呢?你这是为了上技术而上技术,乱用(对不起我承认)然后他沉默了一分钟很不爽,《你这样子设计根本就没考虑开销》别骂我了,我以后再也不用马丁星球的任何东西了,我也知道是屎但我个人项目没啥东西了SSE,GPT3.5,WebSocket我反问他对我有什么建议,他说你觉得自己怎么样(WTF,我也就一个幂等性没答出来),他说除了一个其他也错的离谱我问他哪里错的离谱,他说你自己去看吧,刚刚面的那么多,后面我继续问哪里错了?他说不记得了,反正错的离谱?WTF?WTF?WTF?错的离谱?JWT管理我没说错啊,LinkedQueue无界队列不知道他是急了还是啥能问出《现在就有一个业务有10的九次方个任务呢?》,我去可能他在jwt那里就没理解我说的,无所谓了我也就一个幂等性没答出来而且我不懂为啥要用一个UUID作为Key然后用户信息作为Value去存用户信息,感觉这里是为了反驳jwt的设计而反驳了可能干全栈的喜欢用Session吧不懂,休息去了感觉面试官是为了黑我而黑我,最后我让他对我提出建议,他说我有很大的问题,我说具体在哪,他说他忘了😂😂😂让我回去自己想想难绷的一比😂😂,如果我真有大问题他肯定记得很清楚吧,因为某技术点就把个人情绪带进来南蚌南蚌,这个面试官看不爽把我挂了我要笑死了&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
点赞 评论 收藏
分享
科大讯飞2025届春招面经汇总(技术岗+非技术岗)1.&nbsp;技术岗(Java/大数据/算法方向)面试流程:笔试&nbsp;→&nbsp;技术一面&nbsp;→&nbsp;技术二面&nbsp;→&nbsp;HR面笔试:编程题(2道,********中等难度,如动态规划、图论)八股文(数据库、操作系统、网络)项目相关(如Redis缓存优化、JWT认证)技术一面(1小时):Java基础:HashMap&nbsp;vs&nbsp;ConcurrentHashMap(底层结构、线程安全)JUC包工具类(如AQS、线程池)JWT结构及安全性问题数据库:MySQL索引优化(B+树&nbsp;vs&nbsp;Hash索引)优惠券超卖问题(分布式锁实现方案)系统设计:设计一个延迟订单取消系统(定时任务&nbsp;vs&nbsp;消息队列)技术二面(1小时):项目深挖:介绍一个高并发项目(如秒杀系统)如何优化SQL查询性能?算法题:手撕代码:合并K个有序链表(优先队列实现)时间复杂度分析及优化场景题:如何设计一个实时数据仓库(Flink+Kafka)HR面(30分钟):职业规划、加班接受度、期望薪资2.&nbsp;产品运营岗面试流程:群面&nbsp;→&nbsp;业务面&nbsp;→&nbsp;HR面群面(案例分析):设计一个AI教育产品的推广方案讨论用户增长策略(如K12市场)业务面(45分钟):项目经历:在团队中的职责、遇到的困难及解决方案最有成就感的一件事(需量化结果)行业洞察:如何看待AI+教育的发展趋势?如何发现用户需求?(用户调研/数据分析)HR面(30分钟):个人优缺点、为什么选择科大讯飞?3.&nbsp;测试工程师岗面试流程:笔试&nbsp;→&nbsp;技术一面&nbsp;→&nbsp;技术二面技术一面:测试基础:白盒测试&nbsp;vs&nbsp;黑盒测试单元测试框架(如JUnit)编程题:手写一个二分查找算法操作系统:进程&nbsp;vs&nbsp;线程(通信方式)技术二面:项目相关:如何设计自动化测试框架?遇到过哪些Bug?如何定位?场景题:如何测试一个语音识别系统?💡&nbsp;面试建议1.&nbsp;技术岗:刷题:********高频题(动态规划、链表、二叉树)八股文:重点复习JUC、MySQL索引、分布式锁项目复盘:准备1-2个高并发/大数据项目,突出优化点2.&nbsp;非技术岗:熟悉科大讯飞业务(如AI教育、医疗)准备用户增长/产品运营案例分析3.&nbsp;反问环节:可问团队技术栈、新人培养计划🌟&nbsp;科大讯飞面试特点技术岗:偏重底层原理(如HashMap红黑树转换)非技术岗:关注行业洞察与执行力HR面:可能涉及加班文化(部分岗位需接受弹性工作制)内推链接:https://campus.iflytek.com?refrenceCode=BB37621内推码:BB37621&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
点赞 评论 收藏
分享
评论
1
3
分享

创作者周榜

更多
牛客网
牛客企业服务