skip to content

What happens when you add @EnableWebMvc to a Spring Boot application, and when should you?

level: seniorimportance: must knowfreq 68%

answer

  1. @EnableWebMvc → imports DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport
  2. Boot auto-config @ConditionalOnMissingBean(WebMvcConfigurationSupport)
  3. adding it makes auto-config back off → lose Jackson/static/error defaults
  4. Boot: implement WebMvcConfigurer, no @EnableWebMvc
  5. equivalent of <mvc:annotation-driven/>

basics

~10 s

@EnableWebMvc turns on Spring's own MVC Java config and disables Boot's WebMvcAutoConfiguration. You then lose Boot's sensible defaults (JSON converters, static resources, error page). In Boot, usually DON'T add it — just implement WebMvcConfigurer.

solid answer

~40 s

@EnableWebMvc imports DelegatingWebMvcConfiguration, which extends WebMvcConfigurationSupport and registers the core MVC beans itself. Boot's WebMvcAutoConfiguration is annotated @ConditionalOnMissingBean(WebMvcConfigurationSupport.class), so the moment @EnableWebMvc puts that bean in the context, the entire auto-configuration backs off. You lose Boot's defaults: preconfigured Jackson message converters, static-resource handlers (/static, /webjars), the default error handling, content negotiation, ConversionService with Boot's formatters, etc. In a Boot app you normally want to KEEP auto-config and just customize, so you implement WebMvcConfigurer WITHOUT @EnableWebMvc — your callbacks then extend Boot's defaults. You'd only use @EnableWebMvc when you deliberately want full manual control of MVC (rare in Boot, common in a plain Spring, non-Boot app). @EnableWebMvc is effectively the Java-config equivalent of the old <mvc:annotation-driven/> XML element.

code

java · 15 lines
java
// Non-Boot Spring: you MUST enable MVC yourself
@Configuration
@EnableWebMvc
public class PlainSpringMvcConfig implements WebMvcConfigurer {
    // registers MVC infrastructure beans via WebMvcConfigurationSupport
}

// Spring Boot: DO NOT add @EnableWebMvc — keep auto-config, just customize
@Configuration
public class BootWebConfig implements WebMvcConfigurer {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer c) {
        c.favorParameter(true).parameterName("format");
    }
}

go deeper

for a junior

Should know Boot apps usually don't need @EnableWebMvc.

for a middle

Should know that adding it disables Boot's MVC defaults and lists a couple examples (JSON, static resources).

for a senior

Should explain the DelegatingWebMvcConfiguration → WebMvcConfigurationSupport import and the @ConditionalOnMissingBean back-off precisely.

for a principal

Should weigh full-control vs inherit-defaults trade-offs and diagnose the static/Jackson symptoms from first principles.

## The two worlds There are two ways MVC's core beans get set up: 1. **Plain Spring (no Boot):** you add **`@EnableWebMvc`** to a `@Configuration` class. This is the explicit opt-in to Spring MVC's annotation-driven Java config — the equivalent of the XML `<mvc:annotation-driven/>`. 2. **Spring Boot:** **`WebMvcAutoConfiguration`** sets everything up automatically with opinionated defaults, and you do **not** add `@EnableWebMvc`. ## What @EnableWebMvc actually does `@EnableWebMvc` is meta-annotated with `@Import(DelegatingWebMvcConfiguration.class)`. `DelegatingWebMvcConfiguration` **extends `WebMvcConfigurationSupport`** — the class that actually declares the `RequestMappingHandlerMapping`, `RequestMappingHandlerAdapter`, the default `HttpMessageConverter`s, the `ConversionService`, etc. `DelegatingWebMvcConfiguration` additionally autowires every `WebMvcConfigurer` bean and delegates the callbacks to them. ## Why it disables Boot's auto-config Boot's `WebMvcAutoConfiguration` carries: ```java @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) ``` Because `@EnableWebMvc` (via `DelegatingWebMvcConfiguration`) puts a `WebMvcConfigurationSupport` bean into the context, that condition becomes false and **the whole `WebMvcAutoConfiguration` backs off**. The result: you get only bare Spring MVC defaults, not Boot's enhanced ones. ## What you lose - Boot's preconfigured **Jackson** `MappingJackson2HttpMessageConverter` (with your `ObjectMapper` customizations / `spring.jackson.*` properties honored). - **Static resource** handlers for `/static/**`, `/public/**`, `/webjars/**`, and cache/version config. - The Boot **error handling** wiring around MVC, default **content negotiation**, and message-source-aware validation defaults. - `WebProperties`/`spring.mvc.*` property binding for things like path matching, locale, format patterns. Symptoms in interviews: "after I added `@EnableWebMvc`, my static resources 404 and my custom `ObjectMapper` stopped being applied" — classic sign that auto-config backed off. ## The correct Boot pattern ```java // NO @EnableWebMvc here @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry r) { ... } } ``` Implementing `WebMvcConfigurer` alone does **not** register a `WebMvcConfigurationSupport` bean, so `WebMvcAutoConfiguration` stays active and your callbacks are invoked in addition to Boot's defaults. ## When @EnableWebMvc is right - A **non-Boot** Spring app (no auto-config exists — you must enable MVC yourself). - A Boot app where you intentionally want to **take over** MVC config entirely and not inherit Boot opinions (uncommon). ## Even lower level If you extend `WebMvcConfigurationSupport` (or `DelegatingWebMvcConfiguration`) directly, you trigger the same back-off as `@EnableWebMvc` and additionally can override bean-factory methods for the deepest customization. In Boot this is almost never needed.

  • A teammate added @EnableWebMvc and now static files under /static return 404. Why?
    @EnableWebMvc registered a WebMvcConfigurationSupport bean, so WebMvcAutoConfiguration (which is @ConditionalOnMissingBean of that type) backed off — including its static-resource handlers for /static, /public, /webjars. Remove @EnableWebMvc and implement WebMvcConfigurer instead.
  • Does extending WebMvcConfigurationSupport have the same effect as @EnableWebMvc in Boot?
    Yes — it also puts a WebMvcConfigurationSupport bean in the context, so Boot's WebMvcAutoConfiguration backs off. It's an even lower-level override and should be avoided in Boot unless you truly need to override the bean-factory methods.

saying these in an interview costs you the question

  • Claiming @EnableWebMvc is required in Spring Boot
  • Thinking @EnableWebMvc just adds to Boot's config rather than replacing/disabling it
  • Not knowing the @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) mechanism
  • Confusing @EnableWebMvc with @EnableWebSecurity or @SpringBootApplication

context