SpringBoot源码系列(9):DispatcherServlet如何被注册进容器

布鸽不鸽 Lv4

前言

在本文中,将探讨DispatcherServlet是怎样被注册到SpringBoot中的

原文地址:https://xuedongyun.cn/post/19203/

注册进容器的原理

DispatcherServletAutoConfiguration

SpringBootweb模块中,有DispatcherServletAutoConfiguration这个自动配置类

1
2
3
4
5
6
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@AutoConfiguration(after = ServletWebServerFactoryAutoConfiguration.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
public class DispatcherServletAutoConfiguration {
}

DispatcherServletConfiguration

DispatcherServletAutoConfiguration中有一个DispatcherServletConfiguration配置类,通过@Configuration注解进行标注。 属性绑定到WebMvcProperties,对应配置项spring.mvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Configuration(proxyBeanMethods = false)
@Conditional(DefaultDispatcherServletCondition.class)
@ConditionalOnClass(ServletRegistration.class)
// 属性绑定到WebMvcProperties,对应配置项"spring.mvc"
@EnableConfigurationProperties(WebMvcProperties.class)
protected static class DispatcherServletConfiguration {

// 向容器中放入DispatcherServlet组件
@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest());
dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest());
dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound());
dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents());
dispatcherServlet.setEnableLoggingRequestDetails(webMvcProperties.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;
}

}

DispatcherServletRegistrationConfiguration

DispatcherServletAutoConfiguration中还有一个DispatcherServletRegistrationConfiguration配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration(proxyBeanMethods = false)
@Conditional(DispatcherServletRegistrationCondition.class)
@ConditionalOnClass(ServletRegistration.class)
@EnableConfigurationProperties(WebMvcProperties.class)
@Import(DispatcherServletConfiguration.class)
protected static class 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) {

// 关键,此处将DispatcherServlet配置到web容器中
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 继承自ServletRegistrationBean

1
public class DispatcherServletRegistrationBean extends ServletRegistrationBean<DispatcherServlet> implements DispatcherServletPath {}
  • 标题: SpringBoot源码系列(9):DispatcherServlet如何被注册进容器
  • 作者: 布鸽不鸽
  • 创建于 : 2023-06-11 16:32:19
  • 更新于 : 2023-06-25 22:56:27
  • 链接: https://xuedongyun.cn//post/19203/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论