如何防止 spring-web 的 spring-boot 自动配置?
How to prevent spring-boot autoconfiguration for spring-web?
我正在使用 spring-boot
并在 maven pom 中添加了 spring-web
依赖项,以利用 RestTemplate
.
现在 spring 尝试初始化一个 EmbeddedServletContext
。我该如何预防?
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
第一招:
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class)
.web(false)
.run(args);
}
第二个:
@Configuration
@EnableAutoConfiguration(exclude = WebMvcAutoConfiguration.class)
public class Application {
供参考:此用例记录在 Spring Boot Reference Guide:
Not all Spring applications have to be web applications (or web services). If you want to execute some code in a main
method, but also bootstrap a Spring application to set up the infrastructure to use, then it’s easy with the SpringApplication
features of Spring Boot. A SpringApplication
changes its ApplicationContext
class depending on whether it thinks it needs a web application or not. The first thing you can do to help it is to just leave the servlet API dependencies off the classpath. If you can’t do that (e.g. you are running 2 applications from the same code base) then you can explicitly call SpringApplication.setWebEnvironment(false)
, or set the applicationContextClass
property (through the Java API or with external properties). Application code that you want to run as your business logic can be implemented as a CommandLineRunner
and dropped into the context as a @Bean
definition.
application.properties:
spring.main.web-environment=false #webEnvironment property
尽管禁用网络环境的传统方法(如@Tim 的回答中所述)在 Spring 启动 2.x 中仍然有效,但是新的首选方法是设置以下 属性
spring.main.web-application-type=none
Here 是定义允许值的枚举
这适用于 Spring 启动 2.x
public static void main(String[] args) {
new SpringApplicationBuilder(MyApplication.class)
.web(WebApplicationType.NONE)
.build()
.run(args);
}
我试图用 Spring Boot 2.06 构建一个 Reactive Web 应用程序并得到这个错误:
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
这个link说明了问题,并提供了两个建议:
I was building a new Spring WebFlux application with Spring Boot.
After downloading the project template from start.spring.io, I added
some third-party dependencies and tried to start the application. Then
I met the error
org.springframework.context.ApplicationContextException: Unable to
start ServletWebServerApplicationContext due to missing
ServletWebServerFactory bean....
The error message is the clue to the solution. It says Unable to start
ServletWebServerApplicationContext, but my project is using WebFlux
and it’s a reactive web project, not a servlet-based Spring Web MVC
project.
Debugging into the Spring source code helped me find the cause. In the
method deduceWebApplicationType of
org.springframework.boot.SpringApplication, the web application type
is set to WebApplicationType.REACTIVE only when classes of Spring Web
MVC is not present in the CLASSPATH.
The solution is easy once the root cause is identified. We can either:
Update Maven dependencies to exclude spring-webmvc, or Set the web
application type to WebApplicationType.REACTIVE explicitly, as shown
below.
@SpringBootApplication class MyApplication
fun main(args: Array<String>) {
val app = SpringApplication(MyApplication::class.java)
app.webApplicationType = WebApplicationType.REACTIVE
app.run(*args)
}
不幸的是,这些解决方案都不适合我。相反,我改编了 geoand 的回复,并将其添加到我的 application.properties
:
spring.main.web-application-type=reactive
瞧!问题已解决!
我正在使用 spring-boot
并在 maven pom 中添加了 spring-web
依赖项,以利用 RestTemplate
.
现在 spring 尝试初始化一个 EmbeddedServletContext
。我该如何预防?
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
第一招:
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class)
.web(false)
.run(args);
}
第二个:
@Configuration
@EnableAutoConfiguration(exclude = WebMvcAutoConfiguration.class)
public class Application {
供参考:此用例记录在 Spring Boot Reference Guide:
Not all Spring applications have to be web applications (or web services). If you want to execute some code in a
main
method, but also bootstrap a Spring application to set up the infrastructure to use, then it’s easy with theSpringApplication
features of Spring Boot. ASpringApplication
changes itsApplicationContext
class depending on whether it thinks it needs a web application or not. The first thing you can do to help it is to just leave the servlet API dependencies off the classpath. If you can’t do that (e.g. you are running 2 applications from the same code base) then you can explicitly callSpringApplication.setWebEnvironment(false)
, or set theapplicationContextClass
property (through the Java API or with external properties). Application code that you want to run as your business logic can be implemented as aCommandLineRunner
and dropped into the context as a@Bean
definition.
application.properties:
spring.main.web-environment=false #webEnvironment property
尽管禁用网络环境的传统方法(如@Tim 的回答中所述)在 Spring 启动 2.x 中仍然有效,但是新的首选方法是设置以下 属性
spring.main.web-application-type=none
Here 是定义允许值的枚举
这适用于 Spring 启动 2.x
public static void main(String[] args) {
new SpringApplicationBuilder(MyApplication.class)
.web(WebApplicationType.NONE)
.build()
.run(args);
}
我试图用 Spring Boot 2.06 构建一个 Reactive Web 应用程序并得到这个错误:
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
这个link说明了问题,并提供了两个建议:
I was building a new Spring WebFlux application with Spring Boot. After downloading the project template from start.spring.io, I added some third-party dependencies and tried to start the application. Then I met the error org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean....
The error message is the clue to the solution. It says Unable to start ServletWebServerApplicationContext, but my project is using WebFlux and it’s a reactive web project, not a servlet-based Spring Web MVC project.
Debugging into the Spring source code helped me find the cause. In the method deduceWebApplicationType of org.springframework.boot.SpringApplication, the web application type is set to WebApplicationType.REACTIVE only when classes of Spring Web MVC is not present in the CLASSPATH.
The solution is easy once the root cause is identified. We can either:
Update Maven dependencies to exclude spring-webmvc, or Set the web application type to WebApplicationType.REACTIVE explicitly, as shown below.
@SpringBootApplication class MyApplication fun main(args: Array<String>) { val app = SpringApplication(MyApplication::class.java) app.webApplicationType = WebApplicationType.REACTIVE app.run(*args) }
不幸的是,这些解决方案都不适合我。相反,我改编了 geoand 的回复,并将其添加到我的 application.properties
:
spring.main.web-application-type=reactive
瞧!问题已解决!