Spring Boot 的嵌入式服务器(如 Tomcat)是如何启动的?如何替换为 Jetty 或 Undertow?

Spring Boot 的嵌入式服务器启动过程

Spring Boot 提供了一种快速和简单的方式来启动 Java 应用程序,尤其是通过嵌入式服务器(如 Tomcat, Jetty, Undertow)实现这一点。这种架构允许开发者将 Web 应用程序打包成一个独立的可执行 JAR 文件,其中包含了需要的 Web 服务器和依赖项。

启动流程
  1. 创建 Spring Boot 应用

    当你创建 Spring Boot 应用时,通常会有一个入口类,这个类会使用 @SpringBootApplication 注解标记,它是一个复合注解,结合了 @Configuration@EnableAutoConfiguration@ComponentScan

    java 复制代码
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class MySpringBootApplication {
        public static void main(String[] args) {
            SpringApplication.run(MySpringBootApplication.class, args);
        }
    }
  2. 自动配置的处理

    Spring Boot 在启动时会通过 @EnableAutoConfiguration 自动配置应用,根据应用依赖项和环境,自动选择合适的嵌入式服务器,并设置其默认配置。

  3. 初始化嵌入式服务器

    Spring Boot 根据 spring.main.web-application-type 设置,决定应用的类型,如果是 Web 应用,则会配置并启动嵌入式服务器。对于传统的 Servlet 应用,默认会使用 Tomcat。

  4. 启动服务器

    一旦 Spring Boot 准备好了所有的 Servlet 和上下文,它会使用嵌入式服务器的 API 启动服务器。对于 Tomcat,代码类似于:

    java 复制代码
    public class TomcatServletWebServerFactory implements WebServerFactory {
        @Override
        public WebServer getWebServer(ServletContextInitializer... initializers) {
            // 实际的 Tomcat 服务器启动逻辑
            Tomcat tomcat = new Tomcat();
            // 配置和初始化
            tomcat.start();
            return new TomcatWebServer(tomcat);
        }
    }

替换嵌入式服务器

Spring Boot 非常灵活,支持通过不同的 Maven 或 Gradle 依赖来替换嵌入式服务器。以下是如何替换 Tomcat 为 Jetty 或 Undertow 的步骤。

1. 替换为 Jetty

如果你想用 Jetty 替换 Tomcat,需要在你的 pom.xmlbuild.gradle 文件中进行如下更改。

Maven:

首先,删除 Tomcat 的依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope> <!-- 将 Tomcat 的作用域改为 provided -->
</dependency>

然后,添加 Jetty 依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

Gradle:

同样,删除 Tomcat 的依赖:

groovy 复制代码
implementation ('org.springframework.boot:spring-boot-starter-tomcat') {
    exclude module: 'spring-boot-starter-tomcat'
}

然后,添加 Jetty 依赖:

groovy 复制代码
implementation 'org.springframework.boot:spring-boot-starter-jetty'
2. 替换为 Undertow

替换为 Undertow 的方式与 Jetty 相似。

Maven:

同样,删除 Tomcat 的依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

然后,添加 Undertow 依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

Gradle:

在构建文件中实现类似的步骤:

groovy 复制代码
implementation ('org.springframework.boot:spring-boot-starter-tomcat') {
    exclude module: 'spring-boot-starter-tomcat'
}
implementation 'org.springframework.boot:spring-boot-starter-undertow'

代码示例

假设我们要创建一个简单的 Spring Boot 应用并将嵌入式 Tomcat 替换为 Jetty,代码结构如下:

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class MySpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class, args);
    }

    @GetMapping("/")
    public String home() {
        return "Hello, Spring Boot with Jetty!";
    }
}

启动应用

在 IDE 中运行 MySpringBootApplication 类,Spring Boot 会启动嵌入式 Jetty 服务器(如果你已经按照上面的步骤进行了配置)。打开浏览器并访问 http://localhost:8080,你应该能看到 "Hello, Spring Boot with Jetty!" 的输出。

总结

Spring Boot 的嵌入式服务器的启动过程较为简单,主要依赖于自动配置功能。使用不同的嵌入式服务器也是非常容易的,只需更改 Maven 或 Gradle 中的依赖即可。这使得开发者可以根据项目需求灵活选择合适的服务器。无论是使用 Tomcat、Jetty 还是 Undertow,Spring Boot 都能有效支持并优化 Java Web 应用程序的开发和部署。

相关推荐
小辰记事本9 小时前
从零读懂RoCEv2数据包构造:从WQE到线缆上的完整旅程
服务器·网络·网络协议·rdma
江公望13 小时前
Ubuntu htop命令,10分钟讲清楚
linux·服务器
哎呦,帅小伙哦13 小时前
Linux 时间:从原子钟到 clock_gettime 的每一面
linux·运维·服务器
张小姐的猫13 小时前
【Linux】多线程 —— 线程互斥
linux·运维·服务器·c++
YuanDaima204814 小时前
Linux 进阶运维与 AI 环境实战:进程管理、网络排错与 GPU 监控
linux·运维·服务器·网络·人工智能
lolo大魔王15 小时前
Linux 数据文件处理实战:排序、搜索、压缩、归档一站式详解
linux·运维·服务器
1892280486116 小时前
NY382固态MT29F32T08GSLBHL8-24QM:B
大数据·服务器·人工智能·科技·缓存
xhbh66616 小时前
网关端口映射和路由器端口转发有什么区别?配置要点全解析
运维·服务器·网络·智能路由器·端口映射·映射·无痕网关
STDD16 小时前
Soulmask《灵魂面具》 专用服务器搭建教程
运维·服务器·github