所有文章

https://www.cnblogs.com/lay2017/p/11775787.html

正文

springboot的自动配置基于SPI机制,实现自动配置的核心要点就是添加一个自动配置的类,SpringBoot MVC的自动配置自然也是相同原理。

本文开始,我们将讨论Springboot下Servlet的web实现。所以,先找到对应的自动配置类。

org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration

DispatcherServletAutoConfiguration自动配置类

我们打开该类

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
//...
}

1、首先注意到,@Configuration表名这是一个配置类,将会被spring给解析。

2、@ConditionalOnWebApplication意味着当时一个web项目,且是Servlet项目的时候才会被解析。

3、@ConditionalOnClass指明DispatcherServlet这个核心类必须存在才解析该类。

4、@AutoConfigureAfter指明在ServletWebServerFactoryAutoConfiguration这个类之后再解析,设定了一个顺序。

总的来说,这些注解表明了该自动配置类的会解析的前置条件需要满足。

其次,DispatcherServletAutoConfiguration类主要包含了两个内部类,分别是

1、DispatcherServletConfiguration

2、DispatcherServletRegistrationConfiguration

顾名思义,前者是配置DispatcherServlet,后者是配置DispatcherServlet的注册类。什么是注册类?我们知道Servlet实例是要被添加(注册)到如tomcat这样的ServletContext里的,这样才能够提供请求服务。所以,DispatcherServletRegistrationConfiguration将生成一个Bean,负责将DispatcherServlet给注册到ServletContext中。

配置DispatcherServletConfiguration

我们先看看DispatcherServletConfiguration这个配置类

@Configuration(proxyBeanMethods = false)
@Conditional(DefaultDispatcherServletCondition.class)
@ConditionalOnClass(ServletRegistration.class)
@EnableConfigurationProperties({ HttpProperties.class, WebMvcProperties.class })
protected static class DispatcherServletConfiguration { //...
}

@Conditional指明了一个前置条件判断,由DefaultDispatcherServletCondition实现。主要是判断了是否已经存在DispatcherServlet,如果没有才会触发解析。

@ConditionalOnClass指明了当ServletRegistration这个类存在的时候才会触发解析,生成的DispatcherServlet才能注册到ServletContext中。

最后,@EnableConfigrationProperties将会从application.properties这样的配置文件中读取spring.http和spring.mvc前缀的属性生成配置对象HttpProperties和WebMvcProperties。

再看DispatcherServletConfiguration这个内部类的内部代码

@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet(HttpProperties httpProperties, WebMvcProperties webMvcProperties) {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest());
dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest());
dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound());
dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents());
dispatcherServlet.setEnableLoggingRequestDetails(httpProperties.isLogRequestDetails());
return dispatcherServlet;
} @Bean
@ConditionalOnBean(MultipartResolver.class)
@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
public MultipartResolver multipartResolver(MultipartResolver resolver) {
// Detect if the user has created a MultipartResolver but named it incorrectly
return resolver;
}

这个两个方法我们比较熟悉了,就是生成了Bean。

dispatcherServlet方法将生成一个DispatcherServlet的Bean对象。比较简单,就是获取一个实例,然后添加一些属性设置。

multipartResolver方法主要是把你配置的MultipartResolver的Bean给重命名一下,防止你不是用multipartResolver这个名字作为Bean的名字。

配置DispatcherServletRegistrationConfiguration

再看注册类的Bean配置

@Configuration(proxyBeanMethods = false)
@Conditional(DispatcherServletRegistrationCondition.class)
@ConditionalOnClass(ServletRegistration.class)
@EnableConfigurationProperties(WebMvcProperties.class)
@Import(DispatcherServletConfiguration.class)
protected static class DispatcherServletRegistrationConfiguration {
//...
}

同样的,@Conditional有一个前置判断,DispatcherServletRegistrationCondition主要判断了该注册类的Bean是否存在。

@ConditionOnClass也判断了ServletRegistration是否存在

@EnableConfigurationProperties生成了WebMvcProperties的属性对象

@Import导入了DispatcherServletConfiguration,也就是我们上面的配置对象。

再看DispatcherServletRegistrationConfiguration的内部实现

@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
@ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet,
WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> multipartConfig) {
DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet,
webMvcProperties.getServlet().getPath());
registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
multipartConfig.ifAvailable(registration::setMultipartConfig);
return registration;
}

内部只有一个方法,生成了DispatcherServletRegistrationBean。核心逻辑就是实例化了一个Bean,设置了一些参数,如dispatcherServlet、loadOnStartup等。

总结

springboot mvc的自动配置类是DispatcherServletAutoConfigration,主要做了两件事:

1)配置DispatcherServlet

2)配置DispatcherServlet的注册Bean

springboot mvc自动配置(一)自动配置DispatcherServlet和DispatcherServletRegistry的更多相关文章

  1. springboot mvc自动配置(目录)

    对于长时间基于spring框架做web开发的我们,springmvc几乎成为了开发普通web项目的标配.本系列文章基于快速启动的springboot,将从源码角度一点点了解springboot中mvc ...

  2. springboot mvc自动配置(三)初始化mvc的组件

    所有文章 https://www.cnblogs.com/lay2017/p/11775787.html 正文 在springboot mvc自动配置的时候,获得了DispatcherServlet和 ...

  3. 全网最深分析SpringBoot MVC自动配置失效的原因

    前言 本来没有计划这一篇文章的,只是在看完SpringBoot核心原理后,突然想到之前开发中遇到的MVC自动失效的问题,虽然网上有很多文章以及官方文档都说明了原因,但还是想亲自看一看,本以为很简单的事 ...

  4. Springboot MVC 自动配置

    Springboot MVC 自动配置 官方文档阅读 https://docs.spring.io/spring-boot/docs/current/reference/html/web.html#w ...

  5. SpringBoot中对SpringMVC的自动配置

    https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#boot-features-developin ...

  6. SpringBoot | 4.1 SpringMVC的自动配置

    目录 前言 1. SpringMVC框架的设计与流程 1.1 SpringMVC框架的示意图 1.2 SpringMVC的组件流程 2. *自动配置的源码分析 2.1 导入Web场景启动器 2.2 找 ...

  7. springboot web项目创建及自动配置分析(thymeleaf+flyway)

    @ 目录 源码分析 webjars thymeleaf thymeleaf语法 springmvc 启动配置原理 集成flyway插件 springboot 创建web项目只需要引入对应的web-st ...

  8. SpringBoot入门(四)——自动配置

    本文来自网易云社区 SpringBoot之所以能够快速构建项目,得益于它的2个新特性,一个是起步依赖前面已经介绍过,另外一个则是自动配置.起步依赖用于降低项目依赖的复杂度,自动配置负责减少人工配置的工 ...

  9. 接管SpringBoot对Activiti的数据源自动配置

    SpringBoot的自动配置真的让人又爱又恨,但还是爱更多一点. SpringBoot想要帮我们自动配置好一切,但是有时候配置的却并不是我们需要的,甚至有时候会默默的坑我们. 我的项目是一个多数据源 ...

随机推荐

  1. nginx里面的location 规则匹配

    nginx location语法 ~ # 区分大小写的正则匹配 location ~ \.(gif|jpg|png|js|css)$ { #规则D } ~* # 不区分大小写的正则匹配(和~的功能相同 ...

  2. LC 456. 132 Pattern

    Given a sequence of n integers a1, a2, ..., an, a 132 pattern is a subsequence ai, aj, ak such that  ...

  3. Flutter常用命令和mac电脑常用命令

    0.  flutter create example_demo  新建flutter项目 1.flutter packages get  安装新增的包 2.flutter run 运行flutter项 ...

  4. 28 Flutter 轮播图 flutter_swiper

    中文地址: https://github.com/best-flutter/flutter_swiper/blob/master/README-ZH.md 基本参数 参数 默认值 描述 scrollD ...

  5. CentOS7下搭建zabbix监控(三)——Zabbix监控服务配置

    CentOS7下搭建zabbix监控(一)——Zabbix监控端配置 CentOS7下搭建zabbix监控(二)——Zabbix被监控端配置 (1).配置Zabbix监控Apache服务 主机名:yo ...

  6. iOS中NSTimer的使用

    1.初始化 + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelect ...

  7. JAVA8 JVM内存结构变了,永久代到元空间

    在文章<JVM之内存结构详解>中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯? ...

  8. 根据DELTA自动生成SQL语句

    上传客户端的CLIENTDATASET.delta到服务器的clientdataset.data,服务端解析clientdataset的数据生成相应的SQL语句. 相对于直接调用datasetprov ...

  9. for miaomiao

    package com.mytest.formiaomiao; import java.util.ArrayList; import java.util.List; import java.util. ...

  10. mysql新建数据库(database)设置为utf8

    CREATE DATABASE IF NOT EXISTS yourdbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci;