skip to content

What is WebMvcConfigurer and how do you use it to customize Spring MVC?

level: juniorimportance: must knowfreq 70%

answer

  1. interface with empty default methods
  2. implement on @Configuration, override only needed hooks
  3. addInterceptors/addFormatters/addViewControllers/configureMessageConverters
  4. additive in Boot when no @EnableWebMvc
  5. all configurer beans collected via composite

basics

~10 s

WebMvcConfigurer is an interface with default (empty) callback methods. You create a @Configuration class implementing it and override only the callbacks you need, like addInterceptors or addViewControllers, to tweak MVC without replacing everything.

solid answer

~40 s

WebMvcConfigurer is a callback interface for customizing Spring MVC's Java configuration. Because all its methods are Java 8 default methods (empty bodies), you implement it on a @Configuration class and override only the hooks you care about. Common callbacks: addInterceptors (register HandlerInterceptors), addFormatters (register Converter/Formatter for type conversion), addViewControllers (map a URL straight to a view, no controller), configureMessageConverters/extendMessageConverters (JSON/XML body conversion), addCorsMappings, addResourceHandlers. In Spring Boot you register a WebMvcConfigurer bean WITHOUT @EnableWebMvc, so Boot's auto-configuration stays active and your callbacks simply add to it. Multiple WebMvcConfigurer beans are allowed — Spring collects them all via a DelegatingWebMvcConfiguration delegate and invokes every one.

code

java · 20 lines
java
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RequestTimingInterceptor())
                .addPathPatterns("/api/**")
                .excludePathPatterns("/api/health");
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToIsoDateConverter());
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
    }
}

go deeper

for a junior

Should know it's an interface you implement on a @Configuration class and override selected callbacks.

for a middle

Should name the main callbacks and know it's additive in Boot; know multiple configurers compose.

for a senior

Should explain the DelegatingWebMvcConfiguration/composite delegation and the configure-vs-extend message-converter distinction.

for a principal

Should reason about ordering across module-provided configurers and interaction with auto-config in a modular codebase.

## What it is `WebMvcConfigurer` is an interface in `org.springframework.web.servlet.config.annotation`. It is the programmatic (Java-config) way to customize Spring MVC's infrastructure — the beans that dispatch HTTP requests to your `@Controller` handler methods (the `DispatcherServlet`, `RequestMappingHandlerAdapter`, `HttpMessageConverter`s, `HandlerInterceptor`s, view resolvers, etc.). Every method on `WebMvcConfigurer` is a Java 8 **default method with an empty body**. That is the whole design point: you `implements WebMvcConfigurer` on a class and override **only** the callbacks relevant to your need — you don't have to implement dozens of methods. ## How you wire it ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry r) { r.addViewController("/login").setViewName("login"); } } ``` Spring's MVC config (`DelegatingWebMvcConfiguration`, activated either by Boot's auto-config or by `@EnableWebMvc`) autowires **all** `WebMvcConfigurer` beans found in the context into a `WebMvcConfigurerComposite` and calls each callback on every one. So you can split customizations across many configurers, and in Boot your configurer is **additive** on top of the framework defaults. ## The key callbacks (this leaf's scope) - **`addInterceptors(InterceptorRegistry)`** — register `HandlerInterceptor`s (pre/post handler hooks: auth checks, logging, timing). You can scope with `.addPathPatterns(...)` / `.excludePathPatterns(...)` and set order via registration sequence. - **`addFormatters(FormatterRegistry)`** — register `Converter<S,T>` and `Formatter<T>` used for binding request params/path variables to typed method arguments (e.g. String → LocalDate, String → an enum or entity). - **`configureMessageConverters(List<HttpMessageConverter<?>>)`** — control the `HttpMessageConverter`s that serialize/deserialize `@RequestBody`/`@ResponseBody` (JSON via Jackson, etc.). **Gotcha:** if you add any converter here, the framework's default converters are NOT registered — you take full ownership of the list. Use **`extendMessageConverters(List<...>)`** instead to keep defaults and just add/reorder. - **`addViewControllers(ViewControllerRegistry)`** — map a URL directly to a view name (or a redirect/status) with no `@Controller` method — handy for static landing/login pages. Other callbacks include `addCorsMappings`, `addResourceHandlers`, `configureContentNegotiation`, `configureAsyncSupport`, `addArgumentResolvers`, `configureViewResolvers`. ## When to use Use `WebMvcConfigurer` for cross-cutting MVC infrastructure config. Do **not** confuse it with per-request beans — it configures the machinery once at startup. In Boot, prefer it over `@EnableWebMvc` unless you deliberately want to take over MVC config entirely. ## Historical note Before Spring 5 you extended the abstract adapter class `WebMvcConfigurerAdapter`; since the interface got default methods that adapter is deprecated — implement the interface directly.

  • Why are all WebMvcConfigurer methods default methods?
    So you can implement the interface and override only the callbacks you need, instead of being forced to provide empty bodies for every method — the pre-Java-8 role of the deprecated WebMvcConfigurerAdapter.
  • Can you have more than one WebMvcConfigurer?
    Yes. Spring injects all of them into a WebMvcConfigurerComposite/DelegatingWebMvcConfiguration and invokes each callback on every configurer, so customizations can be split across classes/modules.

saying these in an interview costs you the question

  • Thinking you must override every method
  • Believing WebMvcConfigurer replaces all MVC config (it's additive in Boot)
  • Confusing it with the deprecated WebMvcConfigurerAdapter as the current approach
  • Thinking only one configurer can exist

context