I found I needed to access the applicationContextClass reflectively in order to reason about whether I needed to change the default. This was specifically when trying to avoid annotation-based @Configuration processing, but I guess there might be other reasons to want to do it. So adding a public accessor for SpringApplication.applicationContextClass would get me where I need to go.
Example code in Spring Init:
WebApplicationType type = getWebApplicationType(application, prepared.getEnvironment()); // assumptions made here
Class<?> contextType = getApplicationContextType(application); // reflective access here
if (type == WebApplicationType.NONE) {
if (contextType == AnnotationConfigApplicationContext.class || contextType == null) {
application.setApplicationContextClass(GenericApplicationContext.class);
}
} else if (type == WebApplicationType.REACTIVE) {
if (contextType == AnnotationConfigReactiveWebApplicationContext.class || contextType == null) {
application.setApplicationContextClass(ReactiveWebServerApplicationContext.class);
}
} else if (type == WebApplicationType.SERVLET) {
if (contextType == AnnotationConfigServletWebServerApplicationContext.class || contextType == null) {
application.setApplicationContextClass(ServletWebServerApplicationContext.class);
}
}
Alternatively we could encapsulate the concern of mapping a WebApplicationType to a default ApplicationContext. Even better would be to optionally avoid reflective instantiation of the ApplicationContext altogether.
Comment From: wilkinsona
@dsyer I've got a prototype for this. Could you please take a look and let us know if it meets your needs?
Comment From: dsyer
The API works. It would be nice to have access to the setter in SpringApplicationBuilder.
Comment From: wilkinsona
Thanks. I've force-pushed an update to the builder. I'm also wondering if we should deprecate the class-based methods. The new approach provides a superset of the capabilities of the class-based approach so it's not clear to me that we need both.
Comment From: dsyer
Kind of would be nice. The only problem with deprecating the old method is that you need it to support configuration via spring.main.application-context-class.
Comment From: wilkinsona
We're going to deprecate the class-based configuration in favour of the factory.
you need it to support configuration via
spring.main.application-context-class
That's not an officially supported property (hence there being no metadata for it) so anyone using it (and ignoring their IDE's warning) will have to find an alternative once the deprecated setter's been removed (Boot 2.6 at the earliest).