【问题标题】:Spring boot enable/disable embedded tomcat with profileSpring Boot 使用配置文件启用/禁用嵌入式 tomcat
【发布时间】:2015-11-11 17:18:04
【问题描述】:

我正在编写一个 Spring Boot 应用程序,它使用几个 @Configuration 类之一,具体取决于 application.properties 文件中设置的 @Profile

其中一个配置类使用 REST 接口,因此我将 spring-boot-starter-web 作为依赖项。

这会启动一个嵌入式 Tomcat 实例,这很好。

问题是,其他配置文件不需要嵌入式服务器(例如,我使用 JMS 来处理传入消息而不是 REST)。

有什么方法可以阻止@SpringBootApplication 默认启动Tomcat,并且只将它用于REST 配置类? 例如,通过使用 @EnableWebMVC 注释该类

这是我的@Configurationclasses 示例:

休息:

@Profile({"REST"})
@Configuration
@EnableWebMvc
public class HttpConfiguration{
 .
 .
 .
}

JMS:

@Profile({"JMS"})
@Configuration
@EnableJms
public class JMSConfiguration{
 .
 .
 .
}

谢谢

【问题讨论】:

  • 为 JMS 配置文件尝试 @SpringBootApplication(exclude={EmbeddedServletContainerFactory.class})。这应该排除 Embedded Servlet 容器的自动配置

标签: spring spring-mvc tomcat spring-boot


【解决方案1】:

使用

@SpringBootApplication(exclude = {EmbeddedServletContainerAutoConfiguration.class, 
                                  WebMvcAutoConfiguration.class})

排除 Spring Boot 对嵌入式 servlet 容器的自动配置。此外,您需要为非 REST 情况设置以下属性,以便 Spring Boot 不会尝试启动 WebApplicationContext(需要 servlet 容器):

spring.main.web-environment=false

然后通过导入 EmbeddedServletContainerAutoConfiguration.class 在您的 REST 配置文件中启用嵌入式 Tomcat(这会将自动配置延迟到加载 REST 配置文件之后:

@Profile({"REST"})
@Configuration
@Import(EmbeddedServletContainerAutoConfiguration.class)
public class HttpConfiguration {
    // ...
}

如果您使用任何EmbeddedServletContainerCustomizers,您还需要导入EmbeddedServletContainerCustomizerBeanPostProcessorRegistrar.class

【讨论】:

  • 谢谢,这绝对看起来是正确的轨道。现在看到这个异常:线程“main”中的异常org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean. at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133) at org.springframework.context.support.AbstractApplicationContext.refresh
  • 我遇到的另一个问题是,在使用 @Import(EmbeddedTomcat.class) 时,server.port 属性被忽略,我被困在端口 8080 上。我设法通过将导入交换到 @Import(EmbeddedServletContainerAutoConfiguration.class) 来克服这个问题那一点,所以直到相关的@Configuration 类被加载之后才尝试自动配置。
  • 前参考我更喜欢使用这个注释来排除自动配置:@EnableAutoConfiguration(exclude = { ... })
  • spring.main.web-environment ,在 springBoot 2.1.8.RELEASE 中已弃用
【解决方案2】:

从 Spring Boot 2.0 开始,只有相关配置文件中的 spring.main.web-application-type=none 可以解决问题。

如果您在 Spring Boot 2.0 中使用多文档 application.yml,添加此块并将 no-web-profile-name 替换为不应具有嵌入式 Web 服务器的配置文件应该可以工作:

---
spring:
  profiles: no-web-profile-name
  main:
    web-application-type: none

【讨论】:

    【解决方案3】:

    @hzpz 和@orid 的回答让我走上了正轨。

    我需要添加

    @SpringBootApplication(exclude = {EmbeddedServletContainerAutoConfiguration.class, 
    WebMvcAutoConfiguration.class})
    

    并设置:

    spring.main.web-environment=false
    

    在我的 application.properties 文件中用于非 Rest 案例。

    【讨论】:

    • 很高兴我能提供帮助,感谢您的信任!但是,作为对我的答案的编辑,您的答案会更好,因为我的答案显然缺少一些关键部分。我自己进行了编辑,以使其成为您问题的正确答案。
    • @hzpz 抱歉,没有意识到我可以编辑其他人的评论。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2016-11-13
    • 2021-03-03
    • 2015-10-06
    • 2017-08-08
    • 2021-04-30
    • 2014-05-29
    • 2015-03-23
    • 2016-12-28
    相关资源
    最近更新 更多