[JAVA] Static resources could not be distributed from WebFlux when @EnableWebFlux was granted in Spring Boot

Conclusion

When using Spring WebFlux as of Spring Boot 2.3.4.RELEASE Using the @EnableWebFlux annotation will prevent static resources from being distributed.

Summary

It was decided to develop a WEB server for the first time in a few years. It's been a while since I've been developing Java and a WEB server, so I decided to use Spinrg Boot, which has a lot of information.

Since Spring WebFlux was added to the Spring Framework while I was not using Java for a while, I decided to use WebFlux because it was a big deal.

After reading the Spring WebFlux documentation for the first time, The application was automatically configured with Spring Boot.

There were no major issues with using WebFlux at this point, but it became necessary to distribute static resources later.

It seems that static resources can be distributed in the same way as Spring MVC if WebFlux is configured with Spring Boot. I thought that if I place the resource in classpath: / static / and access it with a web browser, a response will be returned from the server, but 404 Not Found will be returned.

I wondered if I made a mistake and browsed the Spring Boot documentation, but [it says it can be done](https://docs.spring.io/spring-boot/docs/2.3.4.RELEASE/reference / htmlsingle / # boot-features-webflux-auto-configuration).

Static resources that the documentation says are not distributed are not distributed. I didn't understand the reason, so I checked the WebFlux related auto-configuration of Spring Boot.

Find a configuration for distributing static resources with WebFlux WebFlux Auto Configurationを発見した。

It seems that you are adding static resource mappings with WebFluxConfig # addResourceHandlers (ResourceHandlerRegistry). Add breakpoints in two places, WebFluxConfig # addResourceHandlers (ResourceHandlerRegistry) and WebFlux constructor, Attach the debugger and launch the application. However, the breakpoint did not hit when the application finished launching.

When Spring Boot auto-configuration is not called, there is usually a situation where the conditions for auto-configuration execution are not met due to lack of @Bean or lack of libraries.

When I was looking at the Spring Boot documentation again, thinking that I had overlooked something, I noticed that the document clearly states the cause.

Cause

Spring Boot configures WebFlux with WebFluxAutoConfiguration. This class is given @ConditionalOnMissingBean ({WebFluxConfigurationSupport.class}), so If the implementation of WebFluxConfigurationSupport is registered as @Bean, this auto-configuration will not be executed.

Check the definition of @EnableWebFlux(https://github.com/spring-projects/spring-framework/blob/69921b49a5836e412ffcd1ea2c7e20d41f0c0fd6/spring-webflux/src/main/java/org/springframework/web/reactive/config /EnableWebFlux.java#L90) @Import (DelegatingWebFluxConfiguration.class)is given. SinceDelegatingWebFluxConfiguration is an implementation of WebFluxConfigurationSupport, The WebFluxAutoConfiguration provided by Spring Boot will not work as an auto-configuration due to the ConditionalOnMissingBean`.

Since I added @EnableWebFlux to the @ Configuration class in the Spring WebFlux document I read first. I was convinced that I had to grant it in order to implement the WebFlux application.

However, Spring Boot provides its own WebFluxConfigurationSupport to add functionality to WebFlux, so There was a rule that @EnableWebFlux should not be added when enabling WebFlux in Spring Boot.

The specifications around here were firmly [written] in the Spring Boot documentation (https://docs.spring.io/spring-boot/docs/2.3.4.RELEASE/reference/htmlsingle/#boot-features- webflux-auto-configuration), but I skipped it because it was after reading the Spring WebFlux documentation.

Digression

Spring Boot detects the classpath library and decides whether to configure Spring MVC or Spring WebFlux as a web server.

So, when both Spring MVC and Spring WebFlux libraries are in the classpath, How can I control the web server to enable? I checked it just in case, and specified REACTIVE in the property spring.main.web-application-type of Spring Boot. It seems that you can configure your application with WebFlux.

Judgment of the setting status of spring.main.web-application-type is It is done with the @ConditionalOnWebApplication (type = ConditionalOnWebApplication.Type.REACTIVE) annotation given to WebFluxAutoConfiguration.

If you want to use Spring MVC, specify SERVLET in spring.main.web-application-type.

Recommended Posts

Static resources could not be distributed from WebFlux when @EnableWebFlux was granted in Spring Boot
Specify the encoding of static resources in Spring Boot
How to not start Flyway when running unit tests in Spring Boot
JSESSIONID could not be assigned to the URL when using Spring Security
Static file access priority in Spring boot
Story when moving from Spring Boot 1.5 to 2.1
Changes when migrating from Spring Boot 1.5 to Spring Boot 2.0
Changes when migrating from Spring Boot 2.0 to Spring Boot 2.2
Story when migration could not be done
When @Transactional of Spring Boot does not work
Customize the display when an error such as 404 Not Found occurs in Spring Boot