springmvc中springmvc自动配置分析
如果对SpringBoot不甚了解, 可能会对其just run
的做事方式有所顾虑,
可能会对AutoConfiguration的魔法感到有一丝丝未知的恐惧?也许会认为这个框架太过于简单无法满足需要? 不过,
一旦你了解SpringBoot,这些疑问句都会变成感叹句…, SpringBoot对初学者展示了足够的友好,也同时有极大的灵活性,让我们自己通过自己的做事风格,打造属于自己springboot,追随风的脚步,一起去领略SpringBoot的风采…
本篇讨论springboot中springmvc自动配置分析…
本篇博客基于springboot2.1.6:
springmvc自动配置官方文档
springboot自动配置好了springmvc的大部分配置:
下面是springboot对springmvc的默认配置:
这次的重点分析在WebMvcAutoConfiguration上 .
-
Inclusion of
ContentNegotiatingViewResolver
andBeanNameViewResolver
beans.-
自动配置了ViewResolver:
viewResolver: 根据方法的返回值,得到视图对象view,视图对象决定如何渲染:(转发?还是重定向?)
查看WebMvcAutoConfiguration类中WebMvcAutoConfigurationAdapter类的ContentNegotiatingViewResolver方法 :
易知,查看ContentNegotiatingViewResolver类中的resolveViewName方法 …
-
- . 易知,此方法的目的是 把所有的视图对象挨个进行遍历 …
发现ContentNegotiatingViewResolver就是组合所有的视图解析器的 …
问题来了?我们如何向boot中添加自己的视图解析器 …
由上图可知 , 是遍历ContentNegotiatingViewResolver类中的viewResolvers . 我们把目光聚焦在viewResolvers
通过分析,发现 在ContentNegotiatingViewResolver中有一个初始化方法:
@Override
protected void initServletContext(ServletContext servletContext) {
Collection<ViewResolver> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(obtainApplicationContext(), ViewResolver.class).values();
if (this.viewResolvers == null) {
this.viewResolvers = new ArrayList<>(matchingBeans.size());
for (ViewResolver viewResolver : matchingBeans) {
if (this != viewResolver) {
this.viewResolvers.add(viewResolver);
}
}
}
由第五行代码可以发现是从容器中获取到视图解析器的 … …
所有 ,我们要定制自己的resolver,只需要将自己的视图解析器加入到容器中即可 .
测试:
1), 自定义视图解析器:
在配置类中自定义ViewResolver:
@Bean
public myViewResolver addmyViewResolver(){
return new myViewResolver();
}
public static class myViewResolver implements ViewResolver {
@Override
public View resolveViewName(String s, Locale locale) throws Exception {
return null;
}
}
2),debug方式测试 :在DispatherServel中 doDispather中加上一个断点 …
发现有我们自己定义的myviewResolver
-
Automatic registration of
Converter
,GenericConverter
, andFormatter
beans.-
Converter:装换器 ; 类型使用的Converter , 即是将前端的string类型等数据转换成各种其他的数据格式 .
-
Formatter , 格式转换器 日期 .
也只只需要自己将自定义的格式转换器放置在容器中就会被自动获取,如下图:也是从容器中获取.
WebMvcAutoConfiguration类中WebMvcAutoConfigurationAdapte类的方法:
-
-
Support for
HttpMessageConverters
(covered later in this document).-
springmvc用来转换http请求和响应的: 如 将一个对象转换成 json格式 /
-
HttpMessageConverters\ 从容器中获取;获取所有的HttpMessageConverter\
WebMvcAutoConfiguration中的WebMvcAutoConfigurationAdapter类中有一个方法: public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, @Lazy HttpMessageConverters messageConverters, ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) { this.resourceProperties = resourceProperties; this.mvcProperties = mvcProperties; this.beanFactory = beanFactory; this.messageConverters = messageConverters; this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider .getIfAvailable(); }
采用了懒加载的模式初始化HttpMessageConverters.打开HttpMessageConverters方法.
如果只有一个有参构造器的情况下,一般参数中的值都是要从容器中取出.
HttpMessageConverters中源码分析:可看到一些可变参数数组.,是获取容器中所有的HttpMessageConverter方法
结论:自己给容器中添加HttpMessageConverters,只需要将自己的组件注册到容器中(@Bean,@Component)
-
-
Automatic registration of
MessageCodesResolver
(covered later in this document).定义错误代码生成规则,具体可自行参阅源码
-
Static
index.html
support. //静态资源首页的访问, 自行参照源码 -
Custom
Favicon
support (covered later in this document). -
Support for serving static resources, including support for WebJars (covered later in this document)).
-
Automatic use of a
ConfigurableWebBindingInitializer
bean (covered later in this document).
自定义的ConfigurableWebBindingInitializer来替换默认的,只需将自定义放置到容器中即可
让我们来参照super.getConfigurableWebBindingInitializer();如何进行自定义配置的?
作用是: 初始化webdataBinder,用来将请求数据和javabean进行一一对应,springmvc数据绑定参阅详解.
还有其他的类在org.springframework.boot.autoconfigure.web:web的所有自动场景:
总结:
如何修改springboot的默认配置:
- . 由于在springboot底层大量使用了从容器中获取的设计风格.SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(比如:ViewResolver)将用户配置的和自己默认的组合起来,并不会"覆盖".
2).要找到springboot中在何处获的容器中的bean, 和获取什么bean …
参考:
https://jingyan.baidu.com/article/4ae03de3cbf7383eff9e6bd3.html
https://www.cnblogs.com/zqLoveSym/p/10565087.html
https://my.oschina.net/u/3574106/blog/1820871