You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Integration与Spring Boot:不依赖增减选择启动嵌入式Web服务器

实现同一Jar包运行时选择嵌入式Web服务器的方案

要在同一可执行Jar中动态切换Tomcat、Jetty、Undertow(Servlet栈)或Netty(WebFlux栈),核心思路是将所有服务器依赖打包进Jar,再通过Spring Boot的条件配置或启动阶段干预,激活目标服务器并排除其他服务器的自动配置。以下是具体实现步骤:

1. 配置Pom.xml引入所有服务器依赖

首先把所有需要的嵌入式服务器依赖都加入项目,同时排除Spring Boot Starter默认引入的服务器,避免依赖冲突:

<!-- Servlet 基础依赖(排除默认Tomcat) -->
<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>

<!-- WebFlux 基础依赖(排除默认Netty) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-reactor-netty</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- 引入所有嵌入式服务器依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-reactor-netty</artifactId>
    <scope>compile</scope>
</dependency>

2. 用条件配置实现运行时服务器选择

创建配置类,通过@ConditionalOnProperty注解根据启动参数激活对应的服务器配置:

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
public class WebServerSelectionConfig {

    // Servlet 容器条件配置
    @Configuration
    @ConditionalOnProperty(name = "server.type", havingValue = "tomcat", matchIfMissing = true)
    @Import(ServletWebServerFactoryAutoConfiguration.Tomcat.class)
    static class TomcatConfig {}

    @Configuration
    @ConditionalOnProperty(name = "server.type", havingValue = "jetty")
    @Import(ServletWebServerFactoryAutoConfiguration.Jetty.class)
    static class JettyConfig {}

    @Configuration
    @ConditionalOnProperty(name = "server.type", havingValue = "undertow")
    @Import(ServletWebServerFactoryAutoConfiguration.Undertow.class)
    static class UndertowConfig {}

    // WebFlux Netty 容器配置
    @Configuration
    @ConditionalOnProperty(name = "server.type", havingValue = "netty")
    static class NettyConfig {
        @Bean
        public ReactiveWebServerFactory nettyReactiveWebServerFactory() {
            return new NettyReactiveWebServerFactory();
        }
    }
}

3. 启动时指定服务器类型

通过系统参数server.type和spring.main.web-application-type指定目标服务器:

  • 启动Tomcat(Servlet栈):
    java -jar your-app.jar -Dserver.type=tomcat -Dspring.main.web-application-type=servlet
    
  • 启动Jetty(Servlet栈):
    java -jar your-app.jar -Dserver.type=jetty -Dspring.main.web-application-type=servlet
    
  • 启动Undertow(Servlet栈):
    java -jar your-app.jar -Dserver.type=undertow -Dspring.main.web-application-type=servlet
    
  • 启动Netty(WebFlux栈):
    java -jar your-app.jar -Dserver.type=netty -Dspring.main.web-application-type=reactive
    

4. 可选:通过启动类直接排除自动配置类

如果需要更直接的控制,可以在main方法中根据参数排除不需要的服务器自动配置类:

public static void main(String[] args) {
    String serverType = System.getProperty("server.type", "tomcat");
    SpringApplication app = new SpringApplication(YourApplication.class);

    // 根据服务器类型排除其他自动配置类
    switch (serverType) {
        case "jetty":
            app.setExcludeAutoConfigurations(
                ServletWebServerFactoryAutoConfiguration.Tomcat.class,
                ServletWebServerFactoryAutoConfiguration.Undertow.class
            );
            break;
        case "undertow":
            app.setExcludeAutoConfigurations(
                ServletWebServerFactoryAutoConfiguration.Tomcat.class,
                ServletWebServerFactoryAutoConfiguration.Jetty.class
            );
            break;
        case "netty":
            app.setExcludeAutoConfigurations(
                ServletWebServerFactoryAutoConfiguration.Tomcat.class,
                ServletWebServerFactoryAutoConfiguration.Jetty.class,
                ServletWebServerFactoryAutoConfiguration.Undertow.class
            );
            break;
        default:
            app.setExcludeAutoConfigurations(
                ServletWebServerFactoryAutoConfiguration.Jetty.class,
                ServletWebServerFactoryAutoConfiguration.Undertow.class
            );
            break;
    }

    app.run(args);
}

注意事项

  • 确保所有服务器依赖版本与Spring Boot版本兼容,优先使用Spring Boot Starter管理版本。
  • 若不需要同时支持Servlet和WebFlux栈,可以移除对应基础依赖(如只需要Servlet则删除spring-boot-starter-webflux)。
  • 可通过@ConfigurationProperties或直接在Bean中自定义服务器参数(如端口、线程池大小)。
  • 测试阶段需分别验证每个服务器的启动逻辑,避免依赖冲突或配置遗漏。

内容的提问来源于stack exchange,提问作者al.truisme

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 03:05:29