springboot配置DispatcherServlet
1.spring boot下servlet的web实现,所以首先要找到对应的自动配置类
package org.springframework.boot.autoconfigure.web.servlet;
@Configuration
: 代表这是一个配置类,会被spring解析
@AutoConfigureAfter
: 表示在ServletWebServerFactoryAutoConfiguration
这个类之后再解析,设定一个顺序
@ConditionalOnClass
: 表示DispatcherServlet
这个核心类必须存在才解析该类
@ConditionalOnWebApplication
: 表示如果是一个web项目,并且是Servlet项目才会被解析
总的来说,这些注解表明了该自动配置类会解析的前置条件
2.其次,DispatcherServletAutoConfiguration
类主要包含了两个内部类
DispatcherServletConfiguration
2.DispatcherServletRegistrationConfiguration
DispatcherServletConfiguration
是配置DispatcherServlet
,后者是配置DispatcherServlet
的注册类
注册类:我们知道Servlet
实例是要被添加(注册)到tomcat
这样的ServletContext
容器里面的,这样才能够提供服务,所以这个注册类将生成一个Bean
,负责将DispatcherServlet
给注册到ServletContext
中的
3.DispatcherServletConfiguration
类
@Configuration
: 代表这是一个配置类,会被spring解析
@Conditional
: 表示一个前置条件判断,由DefaultDispatcherServletCondition
实现,主要是判断了是否已经存在了DispatcherServlet
,如果没有才会触发解析
@ConditionalOnClass
: 表示当ServletRegistration
这个类存在的时候才会触发解析,生成的DispatcherServlet
才能注册到ServletContext
容器中
@EnableConfigurationProperties
: 将会从application.properties
这样的配置文件中读取spring.http
和spring.mvc
前缀的属性生成配置对象HttpProperties
和WebMvcProperties
4.看静态内部类DispatcherServletConfiguration
的代码
第一个方法就是实例化一个对象,第二个方法主要是把我们配置MultipartResolver
的Bean
给重命名一下,防止我们不是使用multipartResolver
这个名字作为Bean
的名字
5.看静态内部类DispatcherServletRegistrationConfiguration
@Configuration
: 代表这是一个配置类,会被spring解析
@Conditional
: 这是一个前置判断,DispatcherServletRegistrationCondition
主要判断了该注册类的Bean
是否存在
@ConditionalOnClass
: 判断了ServletRegistration
是否存在
@EnableConfigurationProperties
: 生成了WebMvcProperties
的属性对象
@Import
:导入了DispatcherServletConfiguration
,也就是我们上面的配置对象
6.看静态内部类DispatcherServletRegistrationConfiguration
代码
生成了一个DispatcherServletRegistrationBean
实例对象Bean
,并且设置了一些参数:dispatcherServlet
,loadOnStartup
等
总结:springboot mvc
的自动配置类是DispatcherServletAutoConfiguration
,主要做两件事情:
- 配置
DispatcherServlet
- 配置
DispatcherServlet
的注册Bean
7.DispatcherServletRegistrationBean
类
先看类的继承关系
- 首先
ServletContextInitializer
接口是用来初始化ServletContext
的
@FunctionalInterface
public interface ServletContextInitializer {
void onStartup(ServletContext servletContext) throws ServletException;
}
RegistrationBean
类,看RegistrationBean
类是怎么实现onStartup
类
@Override
public final void onStartup(ServletContext servletContext) throws ServletException {
String description = getDescription();
if (!isEnabled()) {
logger.info(StringUtils.capitalize(description) + " was not registered (disabled)");
return;
}
register(description, servletContext);
}
- 发现
register
调用的试内部的抽象方法
protected abstract void register(String description, ServletContext servletContext);
- 查看实现类
DynamicRegistrationBean
是如何实现这个方法
@Override
protected final void register(String description, ServletContext servletContext) {
D registration = addRegistration(description, servletContext);
if (registration == null) {
logger.info(
StringUtils.capitalize(description) + " was not registered " + "(possibly already registered?)");
return;
}
configure(registration);
}
- 点进去
addRegistration
方法,发现是一个内部抽象方法
protected abstract D addRegistration(String description, ServletContext servletContext);
- 查看实现类
ServletRegistrationBean
@Override
protected ServletRegistration.Dynamic addRegistration(String description, ServletContext servletContext) {
String name = getServletName();
return servletContext.addServlet(name, this.servlet);
}
这里直接将DispatcherServlet
给add
到了ServletContext
中