【Spring Boot】Spring Boot中Spring MVC自动配置分析

springmvc中springmvc自动配置分析


如果对SpringBoot不甚了解, 可能会对其just run的做事方式有所顾虑,
可能会对AutoConfiguration的魔法感到有一丝丝未知的恐惧?也许会认为这个框架太过于简单无法满足需要? 不过,
一旦你了解SpringBoot,这些疑问句都会变成感叹句…, SpringBoot对初学者展示了足够的友好,也同时有极大的灵活性,让我们自己通过自己的做事风格,打造属于自己springboot,追随风的脚步,一起去领略SpringBoot的风采…

本篇讨论springboot中springmvc自动配置分析…


本篇博客基于springboot2.1.6:
springmvc自动配置官方文档

springboot自动配置好了springmvc的大部分配置:

下面是springboot对springmvc的默认配置:

这次的重点分析在WebMvcAutoConfiguration上 .

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

    • 自动配置了ViewResolver:

      viewResolver: 根据方法的返回值,得到视图对象view,视图对象决定如何渲染:(转发?还是重定向?)

      查看WebMvcAutoConfiguration类中WebMvcAutoConfigurationAdapter类的ContentNegotiatingViewResolver方法 :

      在这里插入图片描述

    易知,查看ContentNegotiatingViewResolver类中的resolveViewName方法 …

在这里插入图片描述

  1. . 易知,此方法的目的是 把所有的视图对象挨个进行遍历 …

在这里插入图片描述

发现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, and Formatter 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)

    还可参阅官方文档示例:如何自定义converters

  • 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的默认配置:

  1. . 由于在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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值