web-dev-qa-db-fra.com

Comment empêcher la configuration automatique de Spring-Boot pour Spring-Web?

J'utilise spring-boot et ajouté spring-web dépendance dans maven pom, pour utiliser RestTemplate.

Le printemps essaie maintenant d'initialiser un EmbeddedServletContext. Comment puis-je l'empêcher?

Exception in thread "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(AbstractApplicationContext.Java:474)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.Java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.Java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:957)
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:946)
Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.Java:183)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.Java:156)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.Java:130)
    ... 8 more
30
membersound

Pour référence: ce cas d'utilisation est documenté dans le Spring Boot Reference Guide :

Toutes les applications Spring ne doivent pas être des applications Web (ou des services Web). Si vous voulez exécuter du code dans une méthode main, mais aussi bootstrap une application Spring pour configurer l'infrastructure à utiliser, alors c'est facile avec la SpringApplication fonctionnalités de Spring Boot. Une SpringApplication modifie sa classe ApplicationContext selon qu'elle pense avoir besoin d'une application Web ou non. La première chose que vous pouvez faire pour l'aider est de simplement quitter le servlet Dépendances de l'API hors du chemin d'accès aux classes. Si vous ne pouvez pas le faire (par exemple, vous exécutez 2 applications à partir de la même base de code), vous pouvez appeler explicitement SpringApplication.setWebEnvironment(false), ou définir la propriété applicationContextClass ( via l'API Java API ou avec des propriétés externes). Le code d'application que vous souhaitez exécuter en tant que logique métier peut être implémenté en tant que CommandLineRunner et déposé dans le contexte en tant que @Bean définition.

application.properties:

spring.main.web-environment=false   #webEnvironment property
32
Tim

Première astuce:

public static void main(String[] args) throws Exception {
    ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class)
                .web(false)
                .run(args);
}

Seconde:

@Configuration
@EnableAutoConfiguration(exclude = WebMvcAutoConfiguration.class)
public class Application {
26
Artem Bilan

Bien que la méthode héritée de désactivation de l'environnement Web (comme mentionné dans la réponse de @ Tim) fonctionne toujours dans Spring Boot 2.x, cependant, la nouvelle méthode préférée consiste à définir la propriété suivante

spring.main.web-application-type=none

Ici est l'énumération qui définit les valeurs autorisées

8
geoand

Cela fonctionne dans Spring Boot 2.x

public static void main(String[] args) {
   new SpringApplicationBuilder(MyApplication.class)
            .web(WebApplicationType.NONE)
            .build()
            .run(args);
}
8
Andy

J'essayais de créer une application Web réactive avec Spring Boot 2.06 et j'ai obtenu cette erreur:

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.Java:155) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:542) ~[spring-context-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.Java:140) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.Java:754) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.Java:386) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:307) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1242) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1230) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at com.vogella.springboot2.Test3Application.main(Test3Application.Java:10) [main/:na]
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.Java:204) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.Java:178) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.Java:152) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    ... 8 common frames omitted

Ce lien explique le problème et propose deux suggestions:

https://vividcode.io/Fixing-Spring-Boot-error-Unable-to-start-ServletWebServerApplicationContext-due-to-missing-ServletWebServerFactory-bean/

Je construisais une nouvelle application Spring WebFlux avec Spring Boot. Après avoir téléchargé le modèle de projet à partir de start.spring.io, j'ai ajouté des dépendances tierces et j'ai essayé de démarrer l'application. Ensuite, j'ai rencontré l'erreur org.springframework.context.ApplicationContextException: impossible de démarrer ServletWebServerApplicationContext en raison du bean ServletWebServerFactory manquant ....

Le message d'erreur est l'indice de la solution. Il indique Impossible de démarrer ServletWebServerApplicationContext, mais mon projet utilise WebFlux et c'est un projet Web réactif, pas un projet Spring Web MVC basé sur servlet.

Le débogage dans le code source de Spring m'a aidé à trouver la cause. Dans la méthode deduceWebApplicationType de org.springframework.boot.SpringApplication, le type d'application Web est défini sur WebApplicationType.REACTIVE uniquement lorsque les classes de Spring Web MVC ne sont pas présentes dans CLASSPATH.

La solution est simple une fois que la cause première est identifiée. On peut soit:

Mettez à jour les dépendances Maven pour exclure spring-webmvc, ou définissez explicitement le type d'application Web sur WebApplicationType.REACTIVE, comme indiqué ci-dessous.

@SpringBootApplication class MyApplication
fun main(args: Array<String>) {
    val app = SpringApplication(MyApplication::class.Java)
    app.webApplicationType = WebApplicationType.REACTIVE
    app.run(*args)
}

Malheureusement, aucune de ces solutions n'a fonctionné pour moi. Au lieu de cela, j'ai adapté la réponse de geoand et l'ai ajouté à mon application.properties:

spring.main.web-application-type=reactive

Voila! Problème résolu!

2
FoggyDay