题记
这篇文章将从全局接管和局部角度出发, 来解析WebMvc的配置自定义实现
局部实现
1. 继承WebMvcConfigurerAdapter
但是该方法在spring-webmvc5.0以后被废弃, 因为Java8接口可以有default方法
2. 实现WebMvcConfigurer(推荐)
这也是推荐的方法, 实现该接口会保留自动装配
全局配置
继承WebMvcConfigurationSupport并加入@EnableWebMvc注解
具体解析
- 继承WebMvcConfigurationSupport会导致WebMvcAutoConfiguration失效, 详见代码中的Condition
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
// 只有在WebMvcConfigurationSupport不存在才会生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
- @EnableWebMvc的作用是引入DelegatingWebMvcConfiguration配置类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
- DelegatingWebMvcConfiguration是为了引出WebMvcConfigurerComposite
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
setConfigurers方法会调用WebMvcConfigurerComposite中的addWebMvcConfigurers加所有WebMvcConfigurer实现类添加到delegates数组.这样子所有实现WebMvcConfigure配置都会生效
class WebMvcConfigurerComposite implements WebMvcConfigurer {
private final List<WebMvcConfigurer> delegates = new ArrayList<>();
public void addWebMvcConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.delegates.addAll(configurers);
}
}
WebMvcAutoConfiguration中有一个静态内部类继承了DelegatingWebMvcConfiguration, 所以不需要@EnableWebMvc注解
@Configuration(proxyBeanMethods = false)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
常用配置方法
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 添加静态资源的路径映射
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
/**
* 添加对跨域的支持
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")
.allowCredentials(true)
.maxAge(3600 * 24);
}
/**
* 添加拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
}
/**
* 自定义视图
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
}
/**
* 自定义消息转换
* @param converters
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
}