Spring Boot, @EnableWebMvc, and Common Use Cases
Have you noticed strange behavior when using the @EnableWebMvc annotation in Spring Boot? No? Well, how's your autoconfiguration doing?
Join the DZone community and get the full member experience.
Join For FreeIt turns out that Spring Boot doesn’t mix well with the standard Spring MVC @EnableWebMvc
. What happens when you add the annotation is that Spring Boot's autoconfiguration is disabled.
The bad part (that wasted me a few hours) is that in no guide you can find that explicitly stated. In this guide, it says that Spring Boot adds it automatically, but doesn’t say what happens if you follow your previous experience and just put the annotation.
In fact, people that are having issues stemming from this automatically disabled autoconfiguration, are trying to address it in various ways. Most often – by keeping @EnableWebMvc, but also extending Spring Boot’s WebMvcAutoConfiguration
. Like here, here, and somewhat here. I found them after I got the idea and implemented it that way. Then I realized doing it is redundant, after going through Spring Boot’s code and seeing that an inner class in the autoconfiguration class has a single-line javadoc stating
"Configuration equivalent to {@code @EnableWebMvc}."
That answered my question as to whether Spring Boot autoconfiguration misses some of the EnableWebMvc “features”. And it’s good that they extended the class that provides EnableWebMvc, rather than mirroring the functionality (which is obvious, I guess).
What should you do when you want to customize your beans? As usual, extend WebMvcConfigurerAdapter
(annotate the new class with @Component
) and do your customizations.
So, bottom line of the particular problem: Don’t use @EnableWebMvc in Spring Boot, just include spring-web as a maven/gradle dependency and it will be autoconfigured.
The bigger picture here resulted in me adding a comment in the main configuration class detailing why @EnableWebMvc
should not be put there. So the autoconfiguration magic saved me doing a lot of stuff, but I still added a line explaining why something isn’t there.
And that’s because of the common use-cases – people are used to using @EnableWebMvc
. So the most natural and common thing to do is to add it, especially if you don’t know how spring boot autoconfiguration works in detail. And they will keep doing it, and wasting a few hours before realizing they should remove it (or before extending a bunch of boot’s classes in order to achieve the same effect).
My suggestion in situations like this is: log a warning. And require explicitly disabling autoconfiguration in order to get rid of the warning. I had to turn on debug to see what gets autoconfigured, and then explore a bunch of classes to check the necessary conditions in order to figure out the situation.
And one of Spring Boot’s main use-cases is JAR-packaged web applications. That’s what most tutorials are for, and that’s what it’s mostly used for, I guess. So there should be special treatment for this common use case – with additional logging and logged information helping people get through the maze of autoconfiguration.
I don’t want to be seen as “lecturing” the Spring team, who have done an amazing job in having good documentation and straightforward behaviour. But in this case, where multiple sub-projects “collide”, it seems it could be improved.
Published at DZone with permission of Boz Hogan. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments