Spring Boot 使用配置文件启用/禁用嵌入式 tomcat

Posted

技术标签:

【中文标题】Spring Boot 使用配置文件启用/禁用嵌入式 tomcat【英文标题】:Spring boot enable/disable embedded tomcat with profile 【发布时间】: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 容器的自动配置 【参考方案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 抱歉,没有意识到我可以编辑其他人的评论。感谢您的帮助。

以上是关于Spring Boot 使用配置文件启用/禁用嵌入式 tomcat的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用嵌入式数据库 Spring-boot spring-data-jpa

可以使用属性启用/禁用 Spring Boot @RestController 吗?

使用基本身份验证配置 Spring Boot 的嵌入式 tomcat 容器

使用 IntelliJ 部署启用嵌入式 tomcat 的 spring-boot 应用程序

使用 Spring Boot 和嵌入式 Tomcat 启用会话持久性

Liquibase 与 Spring Boot 多个数据源,其中一个已禁用