没有 Web 服务器的 Spring 启动

我有一个简单的 Spring Boot 应用程序,它可以从 JMS 队列获取消息,并将一些数据保存到日志文件中,但不需要 Web 服务器。有没有办法在没有 Web 服务器的情况下启动 SpringBoot?

150662 次浏览

如果在类路径上没有 Tomcat 依赖项,Spring 启动将不包含嵌入的 Tomcat。 您可以在类 EmbeddedServletContainerAutoConfiguration中查看这个事实,您可以找到源 给你

代码的核心是在类 EmbeddedTomcat上使用 @ConditionalOnClass注释


此外,更多的信息查看 这个这个指南和 这个部分的文档

如果您想在没有 servlet 容器的情况下运行 SpringBoot1.x,但是在类路径上有一个 servlet 容器(例如用于测试) ,请使用以下方法,如 弹簧启动文档中所述:

@Configuration
@EnableAutoConfiguration
public class MyClass {
public static void main(String[] args) throws JAXBException {
SpringApplication app = new SpringApplication(MyClass.class);
app.setWebEnvironment(false); //<<<<<<<<<
ConfigurableApplicationContext ctx = app.run(args);
}
}

还有,我偶然发现了一处房产:

spring.main.web-environment=false

如果你想使用 spring.io 站点的“ Get Started”模板,但是你不需要“ default”(“ gs/spring-boot”)模板中任何与 servlet 相关的东西,你可以尝试调度任务模板(它的 pom * 包含 spring-boot-starter 等) :

Https://spring.io/guides/gs/scheduling-tasks/

这样就可以启动 Spring Boot,而且应用程序是独立运行的(pom 中不包含 servlet 或 Spring-webmvc 等)。这正是您想要的(尽管您可能需要添加一些特定于 JMS 的内容,正如其他人已经指出的那样)。

[ * 我使用的是 Maven,但是假设 Gradle 版本的工作方式与 Maven 类似]。

你可以创建这样的东西:

@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(false).run(args);
}
}

还有

@Component
public class CommandLiner implements CommandLineRunner {


@Override
public void run(String... args) throws Exception {
// Put your logic here
}


}

但是依赖项仍然存在,但是没有使用。

SpringBoot2.x,3. x

  • 申请资格

      spring.main.web-application-type=NONE
    # REACTIVE, SERVLET
    
  • 或者是 SpringApplicationBuilder

      @SpringBootApplication
    public class MyApplication {
    
    
    public static void main(String[] args) {
    new SpringApplicationBuilder(MyApplication.class)
    .web(WebApplicationType.NONE) // .REACTIVE, .SERVLET
    .run(args);
    }
    }
    

地点:

  • NONE-应用程序不应该作为 Web 应用程序运行,也不应该启动嵌入式 Web 服务器。
  • REACTIVE-应用程序应该作为一个反应式 Web 应用程序运行,并且应该启动一个嵌入式反应式 Web 服务器。
  • SERVLET-应用程序应该作为一个基于 servlet 的 web 应用程序运行,并且应该启动一个嵌入式 servlet web 服务器。

最简单的解决方案。在 application.properties 文件中。按照前面的答案添加以下属性:

Web 环境 = false

对于 Spring 启动器的2.0.0版本,请使用以下属性:

Web-application-type = none

对于关于所有属性的文档,请使用以下链接: https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

  • 通过程序:

    ConfigurableApplicationContext ctx =  new  SpringApplicationBuilder(YourApplicationMain.class)
    .web(WebApplicationType.NONE)
    .run(args);
    
  • Through application.properties file :

    spring.main.web-environment=false
    
  • Through application.yml file :

    spring:
    main:
    web-environment:false
    

如果您的应用程序中需要 Web 功能(比如用于 REST 调用的 org.springframework.web.client.RestTemplate) ,但您不想启动 TOMCAT 服务器,只需将其排除在 POM 中:

<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>

对于 Spring boot v2.1.3. RELEASE,只需将以下属性添加到 application.properties:

spring.main.web-application-type=none

删除以下依赖于您的 pom 文件将为我工作

  <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

用这个密码。

SpringApplication application = new SpringApplication(DemoApplication.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);

对于科特林来说,这是我最近使用的:


// src/main/com.blabla/ShellApplication.kt


/**
* Main entry point for the shell application.
*/
@SpringBootApplication
public class ShellApplication : CommandLineRunner {
companion object {
@JvmStatic
fun main(args: Array<String>) {
val application = SpringApplication(ShellApplication::class.java)
application.webApplicationType = WebApplicationType.NONE
application.run(*args);
}
}


override fun run(vararg args: String?) {}
}


// src/main/com.blabla/command/CustomCommand.kt


@ShellComponent
public class CustomCommand {
private val logger = KotlinLogging.logger {}


@ShellMethod("Import, create and update data from CSV")
public fun importCsv(@ShellOption() file: String) {
logger.info("Hi")
}
}

所有引导通常都以一个 shell 结束,并且可以使用我的自定义命令。

与上面的@nayun oh 答案相似,但是对于旧版本的 Spring,使用以下代码:

SpringApplication application = new SpringApplication(DemoApplication.class);
application.setApplicationContextClass(AnnotationConfigApplicationContext.class);
application.run(args);

你可以使用 spring-boot-starter 依赖项,这里没有 web 内容。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

在 Spring 引导中,SpringWeb 依赖项提供了一个嵌入式 ApacheTomcatweb 服务器。如果删除 pom.xml 中的 弹簧启动网依赖项,那么它就不会提供嵌入式 Web 服务器。

删除以下依赖项

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

Spring 启动有很多启动程序,有些启动程序有嵌入式 Web 服务器,有些没有。以下是嵌入式网络伺服器:

spring-boot-starter-web
spring-boot-starter-data-jpa
spring-boot-starter-jetty
spring-boot-starter-tomcat
spring-boot-starter-jdbc
spring-boot-starter-data-rest
...

选择一个满足您的需求并且不支持服务器的服务器。

我只需要在我的春季应用程序中提出宁静的 jsonapi 请求,所以我需要的启动器是

spring-boot-starter-json

提供 RestTemplatejackson供我使用。

根据我在 弹簧靴 > 2.5的经验,

  • 如果您计划将应用程序构建为 jar文件 ,我认为 spring.main.web-application-type=NONE的解决方案不应该被广泛接受和使用,因为它的好处有限。

    如果要求在没有 Web 服务器的情况下进行 Spring 启动,这意味着您需要从 Spring 获得构建 Spring Web 应用程序的依赖关系 spring-boot-starter-web或构建 jax-rs Web 应用程序的依赖关系 spring-boot-starter-jersey。这些依赖关系打包在 spring-boot-starter-tomcat中,然后带来实际的 tomcat 服务器 tomcat-embed-core的依赖关系。这个库是自动打包在里面的,是 大小 ~ 3.3 MB的。即使使用前面提到的属性禁用服务器,您仍然会交付应用程序 jar文件,其中包含 tomcat 服务器。

    因此,只使用上述属性的 骗局是,可交付罐文件的大小将比实际需要的大一些。

    因此,如果你想有弹簧启动没有网络服务器 只是不要使用依赖关系 ABC0或 spring-boot-starter-web因为如果您将应用程序构建为 jar文件,那么就没有理由拥有这些依赖项,也没有理由不交付嵌入式服务器。

  • 如果计划将应用程序构建为 war文件 ,也不应使用上述属性。 在这种情况下,您只需要在 .pom中使用以下配置

    <packaging>war</packaging>
    
    
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web or (spring-boot-starter-jersey)</artifactId>
    <exclusions>
    <exclusion>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>pick the version that the server that already runs in production supports</version>
    <scope>provided</scope>
    </dependency>
    </dependencies>
    
  • 特殊情况

    在我看来,spring.main.web-application-type=NONE属性应该用于一些特殊情况,比如,如果我们构建了一些 web library,它需要上述依赖关系,但不能像 Web 应用程序那样使用,或者我们有一些复杂类型的测试,它需要这些库,尽管应用程序不需要任何服务器来运行。然而,这种用法很少见。