spring-boot
spring-boot copied to clipboard
Support DevTools remote update in reactive web applications
Hello,
I am creating spring-boot application (version 2.0.1.RELEASE
) using kotlin (1.2.41
), java 8 (Oracle's JDK 1.8.0.172
) and webflux provided by boot:spring-boot-starter-webflux
starter. The application entry point looks like following
@SpringBootApplication
class DemoApplication
fun main(args: Array<String>) {
val springApplication = SpringApplication(DemoApplication::class.java)
springApplication.webApplicationType = WebApplicationType.REACTIVE
springApplication.run()
}
it works fine from webflux stack perspective but it does not allow to use any functionality from spring-boot-devtools
and Remote Update in particular. I've detected that devtools-related beans such as DispatcherFilter
, UrlHandlerMapper
, HttpRestartServerHandler
etc were registered successfully in the context but the only issue is that webcontext of embedded tomcat is not aware of them at all. So, even filter bean was registered in the context it is not a part of embedded tomcat servlet context and it does not receive any incoming requests.
Need to note that I am aware of completely different conception of webflux/reactive flow comparing to old-way servlets/filtes flow. But at the same time I see no reason not to have devtools
available within REACTIVE web application type. Please correct me if I am wrong.
Here is an example how it was possible to run devtools
using TomcatReactiveWebServerFactory
(was inspired mostly by this approach https://stackoverflow.com/a/48790976)
@Configuration
public class RemoteDevToolConf {
@Autowired
DispatcherFilter remoteDevToolsDispatcherFilter;
@Bean
public WebServerFactoryCustomizer<TomcatReactiveWebServerFactory> customizer() {
return factory -> factory.addContextCustomizers(
context -> {
context.addFilterDef(remoteToolFilterDefinition());
context.addFilterMap(devToolFilterMapping());
}
);
}
@NotNull
private FilterDef remoteToolFilterDefinition() {
FilterDef filterDef = new FilterDef();
filterDef.setFilterName("remoteDevToolsDispatcherFilter");
filterDef.setFilter(remoteDevToolsDispatcherFilter);
return filterDef;
}
@NotNull
private FilterMap devToolFilterMapping() {
FilterMap filterMap = new FilterMap();
filterMap.setFilterName("remoteDevToolsDispatcherFilter");
filterMap.addURLPattern("/*");
return filterMap;
}
}
Well, after such a workaround (mostly because it works fine with tomcat and won't work fine with netty where we can't customise servlet context in a such way AFAIK) remote restart works fine and a URI .~~spring-boot!~/restart
is available for clients.
My questions are following:
- Any reasons why
spring-boot-devtools
doesn't work out of the box with REACTIVE application context? Having said that is it an issue or explicitly defined behaviour? - Any drawbacks in usage of devtools filters in a provided manner (ignoring the fact that it works fine with tomcat only so it can be handled by
@ConditionalOn
from what I feel)?