Spring Boot sin el servidor web


104

Tengo una aplicación Spring Boot simple que recibe mensajes de una cola JMS y guarda algunos datos en un archivo de registro, pero no necesita un servidor web. ¿Hay alguna forma de iniciar Spring Boot sin el servidor web?


3
Si no necesita web, no lo incluya, cuando no esté incluido, el servidor integrado no se iniciará. Solo necesitaría el padre inicial y agregar spring-jms(supongo) como una dependencia. Luego, simplemente inicie la aplicación, no se iniciará ningún servidor.
M. Deinum


1
Estás equivocado, solo utilizo spring-boot-starter-batch, no incluyo ninguna configuración de Tomcat u otra configuración de servidor en mi pom.xml, sin embargo, al ejecutar la aplicación se inicia un contenedor web. Debe tener un parámetro en alguna parte.
Mehdi

Respuestas:


25

Spring boot no incluirá tomcat incrustado si no tiene dependencias de Tomcat en la ruta de clase. Puede ver este hecho usted mismo en la clase EmbeddedServletContainerAutoConfigurationcuya fuente puede encontrar aquí .

La esencia del código es el uso de la @ConditionalOnClassanotación en la clase.EmbeddedTomcat


Además, para obtener más información, consulte esta y esta guía y esta parte de la documentación.


En su versión actual, el gs-convert-jar-to-war/completeproyecto de Maven no añadir un servidor Tomcat incluido, a pesar de la spring-boot-starter-tomcatdependencia declarada de alcance provided. Esto se siente como un error. También vea stackoverflow.com/q/25991789/923560
Abdull

137

Si desea ejecutar Spring Boot sin un contenedor de servlet, pero con uno en la ruta de clases (por ejemplo, para pruebas), use lo siguiente, como se describe en la documentación de Spring Boot :

@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);
    }
}

Además, me encontré con esta propiedad:

spring.main.web-environment=false

12
Simplemente agregar la propiedad application.propertiesfunciona perfectamente bien.
Wim Deblauwe

8
Esto funciona pero está obsoleto en Spring Boot 2.0. Vea esta respuesta para la versión 2.0: stackoverflow.com/a/44394305/66686
Jens Schauder

1
FYI: esta propiedad spring.main.web-environmentahora está en desuso. Todavía funciona para Boot 2.1.1
Sergey Karpushin

1
Arranque 2.x - application.setWebApplicationType (WebApplicationType.NONE);
Michael Munsey

1
Lo que se supone que debes usar estos días esspring.main.web-application-type=none
maldito

95

Spring Boot 2.x

  • Propiedades de la aplicación

    spring.main.web-application-type=NONE 
    # REACTIVE, SERVLET
  • o SpringApplicationBuilder

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

Donde WebApplicationType :

  • NONE - La aplicación no debe ejecutarse como una aplicación web y no debe iniciar un servidor web integrado.
  • REACTIVE - La aplicación debe ejecutarse como una aplicación web reactiva y debe iniciar un servidor web reactivo integrado.
  • SERVLET - La aplicación debe ejecutarse como una aplicación web basada en servlet y debe iniciar un servidor web de servlet incorporado.

53

Puedes crear algo como esto:

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

Y

@Component
public class CommandLiner implements CommandLineRunner {

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

}

Sin embargo, la dependencia sigue ahí, pero no se utiliza.


¿Podemos eliminar de forma segura la dependencia sprign-boot-starter-web? Por ahora, hacer que la aplicación no sea web y eliminar esta dependencia causa la excepción ClassNotFound: javax.servlet.ServleContext
Simon Logic

Tenga en cuenta que la solución 1 está obsoleta
ACV


7

Para Spring boot v2.1.3.RELEASE, simplemente agregue las siguientes propiedades en application.propertes:

spring.main.web-application-type=none

6

Utilice este código.

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

3

Si necesita funcionalidad web en su aplicación (como org.springframework.web.client.RestTemplatepara las llamadas REST) ​​pero no desea iniciar un servidor TOMCAT, simplemente exclúyalo en el 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>

3
  • A través del programa:

    ConfigurableApplicationContext ctx =  new  SpringApplicationBuilder(YourApplicationMain.class)
    .web(WebApplicationType.NONE)
    .run(args);
  • A través del archivo application.properties:

    spring.main.web-environment=false 
  • A través del archivo application.yml:

    spring:
     main:
      web-environment:false

2

Si desea utilizar una de las plantillas "Getting Started" del sitio spring.io, pero no necesita ninguna de las cosas relacionadas con el servlet que vienen con la plantilla "predeterminada" ("gs / spring-boot"), puede probar la plantilla de tareas de programación (cuyo pom * contiene spring-boot-starter, etc.) en su lugar:

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

Eso le brinda Spring Boot, y la aplicación se ejecuta de forma independiente (no se incluyen servlets o spring-webmvc, etc. en el pom). Que es lo que quería (aunque es posible que deba agregar algunas cosas específicas de JMS, como alguien más ya señaló).

[* Estoy usando Maven, pero supongo que una compilación de Gradle funcionará de manera similar].


2

Eliminar la dependencia siguiente en su archivo pom funcionará para mí

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

1

Para Kotling, esto es lo que usé últimamente:


// 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")
    }
}

Y todo arranca normalmente terminando con un shell con mi comando personalizado disponible.


1

Puede usar la dependencia spring-boot-starter. Esto no tendrá el material web.

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

0

Similar a @nayun oh respuesta anterior, pero para versiones anteriores de Spring, use este código:

SpringApplication application = new SpringApplication(DemoApplication.class);
application.setApplicationContextClass(AnnotationConfigApplicationContext.class);
application.run(args);
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.