spring设计好美:WebMvcConfigurer
Posted Small leaf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring设计好美:WebMvcConfigurer相关的知识,希望对你有一定的参考价值。
从WebMvcConfigurer了解spring设计的美味
说明
本篇文章主要是讲WebMvcConfigurer设计的巧妙之处。
目的之一:弄清WebMvcConfigurer是什么。
目的之二:WebMvcConfigurer设计中的优点
WebMvcConfigurer是什么
如何使用WebMvcConfigurer
@EnableWebMvc
@Configuration
public class WebConfiguration implements WebMvcConfigurer
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters)
这是一个简单的实现:
spring4.0以前我们是要WebMvcConfigurerAdapter,但是5.0不需要了。
Java8接口新特性:
1.default默认实现。
2.static默认实现。
也就是我们被default标志了的,不需要必须实现了。
WebMvcConfigurerAdapter这个就是把WebMvcConfigurer接口覆盖成了保护类型,我们实现WebMvcConfigurerAdapter不需要把所有的接口方法都实现。
WebMvcConfigurer是什么?我们简单理解就是以前我们以前用xml配置时候的,spring-web.xml。就是我们可以配置很多web方面的组件,比如说消息转化,拦截器,视图转化器,跨域配置,资源控制器等等。我们只需要看接口的注释说明。
我们看spring源码的时候看到注解,只需要点进去,都会有相应的处理方法。
@EnableWebMvc
发现Import(DelegatingWebMvcConfiguration.class)
也就是导入DelegatingWebMvcConfiguration该配置
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport
public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware
DelegatingWebMvcConfiguration:
主要是用来检测Spring容器中有多少WebMvcConfigurer,然后把它加入进来。并且有很多方法这些方法我们可以理解为代理方法。
WebMvcConfigurationSupport就是来做我们web组件的初始化用的,比如HandlerMapping,RequestMappingHandlerAdapter,RequestMappingHandlerMapping
从这里我们知道了如何使用了WebMvcConfigurer
WebMvcConfigurer设计中的优点
设想:如果让你自己设计,例如我要自己扩展消息转化器,现在我们知道了RequestMappingHandlerAdapter.getDefaultArgumentResolvers中
resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
public List<HttpMessageConverter<?>> getMessageConverters()
return this.messageConverters;
。我们知道了RequestMappingHandlerAdapter.getMessageConverters获得消息转化器,我们现在只需要想办法,将它扩展到messageConverters中即可。
设计思想:
1.开放关闭原则。
2.针对接口编程。
1.我们需要写一个接口,这个接口有一个默认的方法setMessageConverters,
2.扩展这个接口,做成一个配置A。
3.在实例化RequestMappingHandlerAdapter是,setMessageConverters的时候,调用一个模板方法,或者将所有A配置收集起来,放入messageConverters即可。
这里我们还需要考虑的几个问题:
1.默认的消息转化器怎么办?
2.如果没有这些配置怎么处理?
我们来看看spring是怎么做的。
@Configuration
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);
@Override
protected void configurePathMatch(PathMatchConfigurer configurer)
this.configurers.configurePathMatch(configurer);
@Override
protected void configureContentNegotiation(ContentNegotiationConfigurer configurer)
this.configurers.configureContentNegotiation(configurer);
@Override
protected void configureAsyncSupport(AsyncSupportConfigurer configurer)
this.configurers.configureAsyncSupport(configurer);
@Override
protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
this.configurers.configureDefaultServletHandling(configurer);
WebMvcConfigurerComposite是什么呢?
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);
@Override
public void configurePathMatch(PathMatchConfigurer configurer)
for (WebMvcConfigurer delegate : this.delegates)
delegate.configurePathMatch(configurer);
从字面理解是一个WebMvcConfigurer代理
我们配置的WebMvcConfigurer均会被添加到WebMvcConfigurerComposite中
而DelegatingWebMvcConfiguration中的其他配置方法都是WebMvcConfigurationSupport的模板方法。
来看
RequestMappingHandlerAdapter如何加载消息转化器的:
protected final List<HttpMessageConverter<?>> getMessageConverters()
if (this.messageConverters == null)
this.messageConverters = new ArrayList<>();
configureMessageConverters(this.messageConverters);
if (this.messageConverters.isEmpty())
addDefaultHttpMessageConverters(this.messageConverters);
extendMessageConverters(this.messageConverters);
return this.messageConverters;
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters)
先去看看有没有配置消息转化器,没有配置就加载默认的,再看看有没有扩展的消息转化器,这里的都是模板方法,都是在DelegatingWebMvcConfiguration中做的。
我当时在想一个问题,DelegatingWebMvcConfiguration不就可以实现吗,为什么还要WebMvcConfigurerComposite?
DelegatingWebMvcConfiguration不用WebMvcConfigurerComposite直接使用List 干嘛这样做呢?
我思考可能是这样的,spring任务,WebMvcConfigurerComposite中添加消息转化器这个功能其实是一个固定的,不会怎么变的,如果我们写成配置的话,就不好了,因为配置会改变,如果日后需要扩展的话又会去动固定的功能。
当然如果我设计的话,我可能就不用WebMvcConfigurerComposite了。
总结
1.WebMvcConfigurer就是我们来配置web请求过程中的一些组建。
2.java8接口可以用default,也可以用static方法。
3.针对接口编程,模板方法。
以上是关于spring设计好美:WebMvcConfigurer的主要内容,如果未能解决你的问题,请参考以下文章
如何在本地主机上启用 Spring 和 Angular 2 之间的 CORS