Spring Boot senza il server web


104

Ho una semplice applicazione Spring Boot che riceve i messaggi da una coda JMS e salva alcuni dati in un file di registro, ma non necessita di un server web. C'è un modo per avviare Spring Boot senza il server web?


3
Se non hai bisogno del web, non includerlo, quando non è incluso il server incorporato non si avvia. Avresti solo bisogno del genitore iniziale e aggiungere spring-jms(immagino) come dipendenza. Quindi avvia l'applicazione, nessun server verrà avviato.
M. Deinum


1
Ti sbagli, io uso solo spring-boot-starter-batch, non includo nessun tomcat o altra configurazione del server nel mio pom.xml, tuttavia l'esecuzione dell'applicazione lancia un web container. Deve prendere un parametro da qualche parte.
Mehdi

Risposte:


25

L'avvio primaverile non includerà tomcat incorporato se non si hanno dipendenze Tomcat dal classpath. Puoi vedere questo fatto tu stesso durante la lezione la EmbeddedServletContainerAutoConfigurationcui fonte puoi trovare qui .

La carne del codice è l'uso @ConditionalOnClassdell'annotazione sulla classeEmbeddedTomcat


Inoltre, per maggiori informazioni consulta questa e questa guida e questa parte della documentazione


Nella sua versione attuale, il gs-convert-jar-to-war/completeprogetto di Maven non aggiungere un server Tomcat incorporato, nonostante la spring-boot-starter-tomcatdipendenza dichiarato con portata provided. Sembra un bug. Vedere anche stackoverflow.com/q/25991789/923560
Abdull

137

se si desidera eseguire spring boot senza un servlet container, ma con uno sul classpath (ad esempio per i test), utilizzare quanto segue, come descritto nella documentazione di 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);
    }
}

inoltre, mi sono appena imbattuto in questa proprietà:

spring.main.web-environment=false

12
Basta aggiungere la proprietà per application.propertiesfunzionare perfettamente.
Wim Deblauwe

8
Funziona ma è deprecato in Spring Boot 2.0. Vedi questa risposta per la versione 2.0: stackoverflow.com/a/44394305/66686
Jens Schauder

1
FYI: questa proprietà spring.main.web-environmentè ora deprecata. Funziona ancora per Boot 2.1.1
Sergey Karpushin

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

1
Quello che dovresti usare in questi giorni èspring.main.web-application-type=none
maledetto

95

Spring Boot 2.x

  • Proprietà dell'applicazione

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

Dove WebApplicationType :

  • NONE - L'applicazione non deve essere eseguita come applicazione Web e non deve avviare un server Web incorporato.
  • REACTIVE - L'applicazione dovrebbe essere eseguita come un'applicazione web reattiva e dovrebbe avviare un server web reattivo incorporato.
  • SERVLET - L'applicazione dovrebbe essere eseguita come un'applicazione web basata su servlet e dovrebbe avviare un server web servlet incorporato.

53

Puoi creare qualcosa di simile:

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

}

La dipendenza è ancora presente ma non utilizzata.


Possiamo rimuovere in modo sicuro la dipendenza sprign-boot-starter-web? Per ora rendere l'app non web e rimuovere questa dipendenza causa l'eccezione ClassNotFound: javax.servlet.ServleContext
Simon Logic

Tieni presente che la soluzione 1 è deprecata
ACV


7

Per Spring Boot v2.1.3.RELEASE, aggiungi semplicemente le seguenti proprietà in application.propertes:

spring.main.web-application-type=none

6

Usa questo codice.

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

3

Se hai bisogno di funzionalità web nella tua applicazione (come org.springframework.web.client.RestTemplateper le chiamate REST) ​​ma non vuoi avviare un server TOMCAT, escludilo semplicemente nel 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
  • Attraverso il programma:

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

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

    spring:
     main:
      web-environment:false

2

Se si desidera utilizzare uno dei modelli "Guida introduttiva" dal sito spring.io, ma non è necessario alcun elemento relativo al servlet fornito con il modello "predefinito" ("gs / spring-boot"), puoi provare invece il modello di attività di pianificazione (il cui pom * contiene spring-boot-starter ecc.):

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

Questo ti dà Spring Boot e l'app funziona come standalone (nessun servlet o spring-webmvc ecc. Sono inclusi nel pom). Che è quello che volevi (anche se potresti dover aggiungere alcune cose specifiche di JMS, come già sottolineato da qualcun altro).

[* Sto usando Maven, ma presumo che una build Gradle funzionerà in modo simile].


2

Rimuovere la seguente dipendenza dal tuo file pom funzionerà per me

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

1

Per Kotling ecco quello che ho usato ultimamente:


// 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 tutto si avvia normalmente finendo con una shell con il mio comando personalizzato disponibile.


1

Puoi usare la dipendenza spring-boot-starter. Questo non avrà il materiale web.

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

0

Simile a @nayun oh answer sopra, ma per le versioni precedenti di Spring, usa questo codice:

SpringApplication application = new SpringApplication(DemoApplication.class);
application.setApplicationContextClass(AnnotationConfigApplicationContext.class);
application.run(args);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.