When building the springboot project, I configured spring.main.web-application-type: reactive in application.yml, but forgot to add the corresponding starter:(spring-boot-starter-weblux). I also added the web starter(spring-boot-starter-web). The error reports given after the program starts are very confusing.

org.springframework.context.ApplicationContextException: Unable to start reactive web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ReactiveWebApplicationContext due to missing ReactiveWebServerFactory bean.
    at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.onRefresh(ReactiveWebServerApplicationContext.java:82)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577)
    at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:64)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:765)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:445)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:338)
    at com.springboot.SpringBoot.main(SpringBoot.java:34)
Caused by: org.springframework.context.ApplicationContextException: Unable to start ReactiveWebApplicationContext due to missing ReactiveWebServerFactory bean.
    at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.getWebServerFactoryBeanName(ReactiveWebServerApplicationContext.java:108)
    at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.createWebServer(ReactiveWebServerApplicationContext.java:90)
    at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.onRefresh(ReactiveWebServerApplicationContext.java:79)
    ... 6 common frames omitted

For my scenario, it is caused by the lack of the corresponding class library. I think it should be verified when the springapplication instance is initially constructed. The error exception should not be reported at the stage of refresh context , and the corresponding exception information means that the corresponding bean is missing, which can't remind me that I forgot to add the corresponding starter.

Comment From: wilkinsona

Thanks for the suggestion. I don't think we can handle this before the context is refreshed as that would require SpringApplication to have quite a deep understanding of the implementation details of how the web server is created. We could definitely improve the error message, though. I think that could be done by throwing a more specific exception for the missing web server factory and then analyzing the exception with a FailureAnalyzer.

Comment From: CangYa2021

@wilkinsona It is necessary to throw a more specific exception. For this scenario, you can deal with this problem before context refresh. Simply put, spring boot does not verify the field of webapplicationtype sufficiently. The field of webapplicationtype has been determined before refreshing the context and will not change later. It is reasonable and necessary to verify the class library that each application type must rely on. For example, I provide an external interface. It is necessary for me to verify the input parameters of this interface. It is a terrible thing for the whole application if related business errors are caused because there is no basic verification action.

Comment From: wilkinsona

I already tried to address this above:

I don't think we can handle this before the context is refreshed as that would require SpringApplication to have quite a deep understanding of the implementation details of how the web server is created.

SpringApplication knows about the different web application types, but it does not know what is required to honour each type. ReactiveWebServerApplicationContext and ServletWebServerApplicationContext know a little bit more, but only that a bean that implements ReactiveWebServerFactory or ServletWebServerFactory is needed. The only way to know for certain if such a bean is available is to refresh the context.

Comment From: CangYa2021

I can understand your idea: business decoupling. I hope to solve this problem myself. Please give me some guidance.

Comment From: wilkinsona

Thanks for the offer. As I said above, I think the approach that we should take is to throw a specific exception for a missing web server factory bean. That would require a change in ReactiveWebServerApplicationContext and ServletWebServerApplicationContext. We'd then add a failure analyser for this exception. There is some guidance on adding a failure analyzer in the reference documentation.

Comment From: philwebb

Closing in favor of PR #30358