【问题标题】:Is it possible to configure the spring boot server explicitly?是否可以显式配置 Spring Boot 服务器?
【发布时间】:2018-11-03 12:10:07
【问题描述】:

我有一个 Spring Boot 应用程序,其中一个依赖项是使用 spring 和嵌入式码头来启动 ad-hoc web 服务器。这会导致我的 Spring Boot 应用程序在码头而不是 tomcat 中启动。

我的 spring-boot-starter-web:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-websocket</artifactId>
    </exclusion>
  </exclusions>
</dependency>

依赖pom:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.integration</groupId>
  <artifactId>spring-integration-http</artifactId>
</dependency>

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
</dependency>

<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-server</artifactId>
</dependency>

<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-servlet</artifactId>
</dependency>

是否有可能将服务器配置为由 spring boot 显式使用,而不是由依赖树推断?

编辑

我进一步调查了该问题并创建了一个 repo 来重现该问题:github.com/svettwer/spring-server-test
org.eclipse.jetty.websocket:javax-websocket-server-impl 导致 spring 以 jetty 启动,而无需任何其他配置。

编辑 2

Spring Boot 2.x 中不再存在该问题

编辑 3 我将删除前面提到的 repo,但这里是导致问题的依赖项设置:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>1.5.7.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>1.5.7.RELEASE</version>
        <scope>test</scope>
    </dependency>

    <!-- Comment that in to start spring with jetty-->
    <dependency>
        <groupId>org.eclipse.jetty.websocket</groupId>
        <artifactId>javax-websocket-server-impl</artifactId>
        <version>9.4.8.v20171121</version>
    </dependency>

</dependencies>

【问题讨论】:

    标签: spring-boot spring-boot-starter


    【解决方案1】:

    通常,如果您的类路径中有spring-boot-starter-tomcat(通过spring-boot-starter-web),它应该始终选择Tomcat,因为它比其他servlet 容器具有优先级。即使你有以下依赖,Spring boot 也会以 Tomcat 启动:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-webapp</artifactId>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-servlet</artifactId>
    </dependency>
    

    您可以通过注册自己的ServletWebServerFactory 以编程方式覆盖所选的 servlet 容器,例如:

    @Bean
    public ServletWebServerFactory factory() {
        return new TomcatServletWebServerFactory();
    }
    

    您可以选择预定义的TomcatServletWebServerFactoryJettyServletWebServerFactoryUndertowServletWebServerFactory

    【讨论】:

    • 为我工作!非常感谢。
    • 我发现ServletWebServerFactory 定义不是必需的。 Spring boot 2.x 解决了这个问题,不需要额外的 bean。
    • @SvenHettwer 这解释了很多。我在第一段中也提到了您通常不需要它。
    【解决方案2】:

    本指南可能会对您有所帮助:https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-web-servers.html

    如果您运行mvn dependency:tree 并搜索jetty,您可能会发现需要将其排除,例如:

    spring-boot-starter-jetty
    

    如示例中一样排除:

        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <!-- Exclude the Tomcat dependency -->
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- Use Jetty instead -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>
    

    这比 tomcat 更喜欢 jetty - 但希望你能明白......

    希望这会有所帮助。

    【讨论】:

    • 排除 org.eclipse.jetty:jetty-server 会在 tomcat 中启动我的应用程序,你是对的。但是因为我想利用依赖的 ad-hoc 服务器功能,所以也需要 jetty-server。因此,我的软件必须保留这两个依赖项才能正常工作。
    • org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration 可能会对您有所帮助(spring boot 2.x)。也许如果您查看顶部的导入(@Import 注释),您会看到它们导入了在内部以缺少 bean 注释为条件的嵌入式配置,因此您也许可以定义自己的 bean 来接管配置。我认为当两者都存在时,tomcat 似乎比码头更受青睐,这就是为什么当包含码头时该示例排除了 tomcat。您如何确定在运行时在 tomcat 上使用了 jetty?
    • 谢谢提示!我会试试这个。 How are you determining that jetty is being used over tomcat at runtime? 我进一步调查了这个问题,并创建了一个 repo 来重现这个问题:github.com/svettwer/spring-server-test org.eclipse.jetty.websocket:javax-websocket-server-impl 导致 spring 从 jetty 启动而无需任何其他配置。
    • 请参阅编辑 3。这只是 Spring Boot
    猜你喜欢
    • 2014-12-20
    • 1970-01-01
    • 2018-07-27
    • 2018-12-25
    • 2015-12-13
    • 2022-12-01
    • 2016-10-26
    • 2017-12-29
    • 2019-03-13
    相关资源
    最近更新 更多