@EnableWebMvc
介绍:
-
将此注解添加到类中会从
WebMvcConfigurationSupport导入 Spring MVC 配置 -
要自定义导入的配置,请实现接口
WebMvcConfigurer并覆盖各个方法 -
只有一个类可以具有导入
@EnalbeWebMVc注解。但是,可以实现有多个类实现WebMvcConfigurer以自定义提供的配置
它只帮我们导入了DelegatingWebMvcConfiguration类,所以把这个类分析明白即可。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class) //导入DelegatingWebMvcConfiguration类
public @interface EnableWebMvc {
}
DelegatingWebMvcConfiguration
主要是将MVC相关的配置委托给一组WebMvcConfigurer实现。
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
// WebMvcConfigurer组合器
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
// 拿到容器中全部的 WebMvcConfigurer,并存到 WebMvcConfigurerComposite 类里面
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
// 剩下的所有方法都是这样的:
// 遍历容器中所有的 WebMvcConfigurer,调用其configureXxx()、addXxx()来读取我们用户自定义的配置
@Override
protected void configurePathMatch(PathMatchConfigurer configurer) {
this.configurers.configurePathMatch(configurer);
}
protected void addInterceptors(InterceptorRegistry registry) {
this.configurers.addInterceptors(registry);
}
...
}
WebMvcConfigurationSupport
这个类帮我们往容器中导入了一堆组件:PathMatchConfigurer、ContentNegotiationManager、HandlerMethodArgumentResolver、HandlerMethodReturnValueHandler、HttpMessageConverter、CorsConfiguration、AsyncSupportConfigurer
具体的可以参照此类上的文档注释或官网的API文档
public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
// RequestMappingHandlerMapping
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
// 省略代码
...
return mapping;
}
// 内容协商管理器
@Bean
public ContentNegotiationManager mvcContentNegotiationManager() {
if (this.contentNegotiationManager == null) {
ContentNegotiationConfigurer configurer = new ContentNegotiationConfigurer(this.servletContext);
configurer.mediaTypes(getDefaultMediaTypes());
configureContentNegotiation(configurer);
this.contentNegotiationManager = configurer.buildContentNegotiationManager();
}
return this.contentNegotiationManager;
}
// RequestMappingHandlerAdapter
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcValidator") Validator validator) {
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
// 省略代码
...
return adapter;
}
// 转换器服务:Converter and/or Formatter
@Bean
public FormattingConversionService mvcConversionService() {
FormattingConversionService conversionService = new DefaultFormattingConversionService();
addFormatters(conversionService);
return conversionService;
}
// 校验器
@Bean
public Validator mvcValidator() {
Validator validator = getValidator();
// 省略代码
...
return validator;
}
// 处理器异常解析器
@Bean
public HandlerExceptionResolver handlerExceptionResolver(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager) {
List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>();
// 省略代码
...
return composite;
}
// 视图解析器
@Bean
public ViewResolver mvcViewResolver(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager) {
ViewResolverRegistry registry =
new ViewResolverRegistry(contentNegotiationManager, this.applicationContext);
// 省略代码
...
ViewResolverComposite composite = new ViewResolverComposite();
// 省略代码
...
return composite;
}
}
总结
@EnableWebMvc的作用:
-
帮我们往容器中注册了一些SpringMVC必要的组件。如:处理器适配器、处理器映射、...
-
拿到我们自定义的
WebMvcConfigurer配置类,读取我们自定义的配置
类图:
-
DelegatingWebMvcConfiguration:会拿到容器中所有的WebMvcConfigurer类,然后依次调用其方法进行配置 -
WebMvcConfigurationSupport:它给容器中导入了一堆组件;并且提供了允许用户自定义配置的方法 -
WebMvcConfigurerComposite:也是一个WebMvcConfigurer,这个类封装了容器中所有的WebMvcConfigurer。以便后续使用 -
WebMvcConfigurer:SpringMVC留给我们的定义底层行为的入口。我们可以通过重写这个类里的方法来自定义配置,定义底层行为