DispatcherServlet初始化流程
DispatcherServlet作为SpringMVC的前端控制器,在启动时完成上下文初始化和核心组件加载。
继承体系
Java
HttpServlet
└── HttpServletBean
└── FrameworkServlet
└── DispatcherServlet
初始化入口
HttpServletBean.init()
Java
public final void init() throws ServletException {
// 解析init-param参数
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig());
// 设置属性
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
bw.setPropertyValues(pvs, true);
// 子类初始化
initServletBean();
}
FrameworkServlet.initServletBean()
Java
protected final void initServletBean() {
try {
// 初始化WebApplicationContext
this.webApplicationContext = initWebApplicationContext();
// 子类扩展点
initFrameworkServlet();
} catch (ServletException ex) {
throw ex;
}
}
WebApplicationContext初始化
initWebApplicationContext()
Java
protected WebApplicationContext initWebApplicationContext() {
// 1. 获取根上下文(Spring容器)
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null;
// 2. 如果已有WebApplicationContext
if (this.webApplicationContext != null) {
wac = this.webApplicationContext;
if (wac instanceof ConfigurableWebApplicationContext) {
configureAndRefreshWebApplicationContext((ConfigurableWebApplicationContext) wac);
}
}
// 3. 查找已存在的WebApplicationContext
if (wac == null) {
wac = findWebApplicationContext();
}
// 4. 创建新的WebApplicationContext
if (wac == null) {
wac = createWebApplicationContext(rootContext);
}
// 5. 刷新上下文(核心)
if (!this.refreshEventReceived) {
synchronized (this.onRefreshMonitor) {
onRefresh(wac);
}
}
return wac;
}
createWebApplicationContext()
Java
protected WebApplicationContext createWebApplicationContext(
@Nullable WebApplicationContext parent) {
Class<?> contextClass = getContextClass();
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Invalid context class");
}
// 实例化AnnotationConfigWebApplicationContext
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
wac.setEnvironment(getEnvironment());
wac.setParent(parent);
String configLocation = getContextConfigLocation();
if (configLocation != null) {
wac.setConfigLocation(configLocation);
}
// 配置并刷新
configureAndRefreshWebApplicationContext(wac);
return wac;
}
核心组件初始化
DispatcherServlet.onRefresh()
Java
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {
// 1. 文件上传解析器
initMultipartResolver(context);
// 2. 区域解析器
initLocaleResolver(context);
// 3. 主题解析器
initThemeResolver(context);
// 4. HandlerMapping
initHandlerMappings(context);
// 5. HandlerAdapter
initHandlerAdapters(context);
// 6. 异常处理器
initHandlerExceptionResolvers(context);
// 7. 请求转视图名转换器
initRequestToViewNameTranslator(context);
// 8. 视图解析器
initViewResolvers(context);
// 9. FlashMap管理器
initFlashMapManager(context);
}
HandlerMapping初始化
Java
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
// 检测所有HandlerMapping
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(
context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<>(matchingBeans.values());
// 排序
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
// 如果没有配置,使用默认策略
if (this.handlerMappings == null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
}
}
HandlerAdapter初始化
properties
private void initHandlerAdapters(ApplicationContext context) {
this.handlerAdapters = null;
Map<String, HandlerAdapter> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(
context, HandlerAdapter.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerAdapters = new ArrayList<>(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerAdapters);
}
if (this.handlerAdapters == null) {
this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
}
}
默认策略加载
DispatcherServlet.properties
Java
# 默认配置文件位置
org.springframework.web.servlet.DispatcherServlet
= org.springframework.web.servlet.DispatcherServlet.properties
# 内容
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.handler.HandlerExceptionResolverComposite
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
getDefaultStrategies()
Java
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
String key = strategyInterface.getName();
String value = defaultStrategies.getProperty(key);
if (value != null) {
String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
List<T> strategies = new ArrayList<>(classNames.length);
for (String className : classNames) {
Class<?> clazz = ClassUtils.forName(className, context.getClassLoader());
T strategy = (T) context.getAutowireCapableBeanFactory().createBean(clazz);
strategies.add(strategy);
}
return strategies;
}
return new LinkedList<>();
}
初始化流程图
text
Servlet容器启动
↓
HttpServletBean.init()
↓ 解析init-param
FrameworkServlet.initServletBean()
↓
initWebApplicationContext()
├─ 获取根上下文(Spring容器)
├─ 创建WebApplicationContext
└─ configureAndRefreshWebApplicationContext()
↓
onRefresh(context)
↓
initStrategies(context)
├─ initMultipartResolver()
├─ initLocaleResolver()
├─ initThemeResolver()
├─ initHandlerMappings()
├─ initHandlerAdapters()
├─ initHandlerExceptionResolvers()
├─ initRequestToViewNameTranslator()
├─ initViewResolvers()
└─ initFlashMapManager()
Spring Boot自动配置
text
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
public class DispatcherServletAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public DispatcherServlet dispatcherServlet() {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setDispatchOptionsRequest(true);
return dispatcherServlet;
}
@Bean
@ConditionalOnMissingBean
public DispatcherServletRegistrationBean dispatcherServletRegistration() {
DispatcherServletRegistrationBean registration =
new DispatcherServletRegistrationBean(dispatcherServlet(), "/");
registration.setName("dispatcherServlet");
registration.setLoadOnStartup(1);
return registration;
}
}
DispatcherServlet初始化时自动检测容器中的组件,若未找到则使用默认策略。
要点总结
- HttpServletBean解析Servlet初始化参数
- FrameworkServlet创建并初始化WebApplicationContext
- onRefresh触发九大核心组件初始化
- 组件初始化优先从容器获取,否则使用默认策略
- Spring Boot通过自动配置简化DispatcherServlet注册
jwdev/articles/SPRINGMVC/专家/MVC核心源码执行流程\MVC核心源码执行流程\DispatcherServlet初始化流程.md
📝 发现内容有误?点击此处直接编辑