全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-18 10 分钟 ✍️ juanwangdev

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初始化时自动检测容器中的组件,若未找到则使用默认策略。

要点总结

  1. HttpServletBean解析Servlet初始化参数
  2. FrameworkServlet创建并初始化WebApplicationContext
  3. onRefresh触发九大核心组件初始化
  4. 组件初始化优先从容器获取,否则使用默认策略
  5. Spring Boot通过自动配置简化DispatcherServlet注册

jwdev/articles/SPRINGMVC/专家/MVC核心源码执行流程\MVC核心源码执行流程\DispatcherServlet初始化流程.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 Spring MVC 自定义返回值处理器HandlerMethodReturnValueHandler
下一篇 → HandlerAdapter调用链
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库