Spring Boot sem o servidor web

104

Eu tenho um aplicativo Spring Boot simples que obtém mensagens de uma fila JMS e salva alguns dados em um arquivo de log, mas não precisa de um servidor web. Existe alguma maneira de iniciar o Spring Boot sem o servidor web?

Michael
fonte
3
Se você não precisa da web, não a inclua; quando não incluída, o servidor incorporado não iniciará. Você só precisaria do pai inicial e adicionaria spring-jms(eu acho) como uma dependência. Em seguida, basta iniciar o aplicativo, nenhum servidor será iniciado.
M. Deinum
1
Você está errado, eu uso apenas spring-boot-starter-batch, não incluo nenhum tomcat ou outra configuração de servidor no meu pom.xml, no entanto, executar o aplicativo inicia um contêiner da web. Deve ter um parâmetro em algum lugar.
Mehdi

Respostas:

25

O Spring boot não incluirá tomcat incorporado se você não tiver dependências do Tomcat no classpath. Você mesmo pode ver esse fato na classe EmbeddedServletContainerAutoConfigurationcuja fonte você pode encontrar aqui .

A essência do código é o uso da @ConditionalOnClassanotação na classeEmbeddedTomcat


Além disso, para obter mais informações, verifique este e este guia e esta parte da documentação

geoand
fonte
Na sua versão atual, o gs-convert-jar-to-war/completeprojeto Maven não adicionar um servidor Tomcat incorporado, apesar da spring-boot-starter-tomcatdependência declarada com escopo provided. Isso parece um bug. Consulte também stackoverflow.com/q/25991789/923560
Abdull
137

se você deseja executar o spring boot sem um contêiner de servlet, mas com um no caminho de classe (por exemplo, para testes), use o seguinte, conforme descrito na documentação do 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);
    }
}

Além disso, acabei de encontrar esta propriedade:

spring.main.web-environment=false
Stefan K.
fonte
12
Apenas adicionar a propriedade a application.propertiesfunciona perfeitamente bem.
Wim Deblauwe
8
Isso funciona, mas está obsoleto no Spring Boot 2.0. Veja esta resposta para a versão 2.0: stackoverflow.com/a/44394305/66686
Jens Schauder
1
Para sua informação: esta propriedade spring.main.web-environmentestá obsoleta. Ainda funciona para o Boot 2.1.1
Sergey Karpushin
1
Boot 2.x - application.setWebApplicationType (WebApplicationType.NONE);
Michael Munsey
1
O que você deveria usar hoje em dia éspring.main.web-application-type=none
maldito
95

Spring Boot 2.x

  • Propriedades do aplicativo

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

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

Onde WebApplicationType :

  • NONE - O aplicativo não deve ser executado como um aplicativo da web e não deve iniciar um servidor da web incorporado.
  • REACTIVE - O aplicativo deve ser executado como um aplicativo da Web reativo e deve iniciar um servidor da Web reativo incorporado.
  • SERVLET - O aplicativo deve ser executado como um aplicativo da web baseado em servlet e deve iniciar um servidor da web de servlet integrado.
Kinjelom
fonte
53

Você pode criar algo assim:

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

E

@Component
public class CommandLiner implements CommandLineRunner {

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

}

A dependência ainda está lá, mas não é usada.

sancho21
fonte
Podemos remover com segurança a dependência sprign-boot-starter-web? Por enquanto, tornar o aplicativo não-web e remover essa dependência causa a exceção ClassNotFound: javax.servlet.ServleContext
Simon Logic
Observe que a solução 1 está obsoleta
ACV
7

Para Spring boot v2.1.3.RELEASE, basta adicionar as seguintes propriedades em application.propertes:

spring.main.web-application-type=none
Chun Hau Lai
fonte
6

Use este código.

SpringApplication application = new SpringApplication(DemoApplication.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);
nayun oh
fonte
3

Se você precisa de funcionalidade da web em seu aplicativo (como org.springframework.web.client.RestTemplatepara chamadas REST), mas não deseja iniciar um servidor TOMCAT, apenas exclua-o no 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>
Paul Rambags
fonte
3
  • Através do programa:

    ConfigurableApplicationContext ctx =  new  SpringApplicationBuilder(YourApplicationMain.class)
    .web(WebApplicationType.NONE)
    .run(args);
    
  • Por meio do arquivo application.properties:

    spring.main.web-environment=false 
  • Por meio do arquivo application.yml:

    spring:
     main:
      web-environment:false
    
Sucheth Shivakumar
fonte
2

Se você quiser usar um dos modelos de "Primeiros passos" do site spring.io, mas não precisa de nenhuma das coisas relacionadas ao servlet que vem com o modelo "default" ("gs / spring-boot"), você pode tentar o modelo de tarefas de agendamento (cujo pom * contém spring-boot-starter etc) em vez disso:

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

Isso dá a você Spring Boot, e o aplicativo é executado como um autônomo (nenhum servlet ou spring-webmvc etc. está incluído no pom). Que é o que você queria (embora possa precisar adicionar algumas coisas específicas do JMS, como alguém já indicou).

[* Estou usando o Maven, mas suponha que uma versão do Gradle funcione de maneira semelhante].

murmelssonic
fonte
2

Remover a seguinte dependência do seu arquivo pom funcionará para mim

  <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
vaquar khan
fonte
1

Para Kotling, aqui está o que usei recentemente:


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

E tudo inicializa normalmente terminando com um shell com meu comando personalizado disponível.

Vincent
fonte
1

Você pode usar a dependência spring-boot-starter. Isso não terá as coisas da web.

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

Semelhante à resposta @nayun oh acima, mas para versões anteriores do Spring, use este código:

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