dispatcherservlet初始化过程详解

KLQ 2020-07-23 15:46:19 java常见问答 8465

之前给大家介绍了什么是dispatcherservlet,以及dispatcherservlet配置等方面的内容,那么下面要接着给大家介绍的就是dispatcherservlet初始化过程,一起来了解一下。

Web容器启动时将调用HttpServletBean的init方法

public abstract class HttpServletBean extends HttpServlet implements EnvironmentAware
{
    @Override
    public final void init() throws ServletException
    {
        //省略部分代码
        //1、如下代码的作用是将Servlet初始化参数设置到该组件上
        //如contextAttribute、contextClass、namespace、contextConfigLocation;
        try
        {
            PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
            BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
            ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
            bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment));
            initBeanWrapper(bw);
            bw.setPropertyValues(pvs, true);
        }
        catch (BeansException ex)
        {
            //…………省略其他代码
        }
        //2、提供给子类初始化的扩展点,该方法由FrameworkServlet覆盖
        initServletBean();
        if (logger.isDebugEnabled())
        {
            logger.debug("Servlet '" + getServletName() + "' configured successfully");
        }
    }
    //…………省略其他代码
}

把Servlet初始化参数(init-param)设置到这个组件上(如contextAttribute、contextClass、namespace、contextConfigLocation),通过BeanWrapper简化设值过程,便于之后使用;

提供给子类初始化扩展点,initServletBean(),这个方法由FrameworkServlet覆盖。

FrameworkServlet通过initServletBean()进行Web上下文初始化

public abstract class FrameworkServlet extends HttpServletBean
{
    @Override
    protected final void initServletBean() throws ServletException
    {
        //省略部分代码
        try
        {
            //1、初始化Web上下文
            this.webApplicationContext = initWebApplicationContext();
            //2、提供给子类初始化的扩展点
            initFrameworkServlet();
        }
        //省略部分代码
    }
}
这个方法主要作用: 初始化web上下文;
提供给子类初始化扩展点;
protected WebApplicationContext initWebApplicationContext()
{
    //ROOT上下文(ContextLoaderListener加载的)
    WebApplicationContext rootContext =
        WebApplicationContextUtils.getWebApplicationContext(getServletContext());
    WebApplicationContext wac = null;
    if (this.webApplicationContext != null)
    {
        // 1、在创建该Servlet注入的上下文
        wac = this.webApplicationContext;
        if (wac instanceof ConfigurableWebApplicationContext)
        {
            ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
            if (!cwac.isActive())
            {
                if (cwac.getParent() == null)
                {
                    cwac.setParent(rootContext);
                }
                configureAndRefreshWebApplicationContext(cwac);
            }
        }
    }
    if (wac == null)
    {
        //2、查找已经绑定的上下文
        wac = findWebApplicationContext();
    }
    if (wac == null)
    {
        //3、如果没有找到相应的上下文,并指定父亲为ContextLoaderListener
        wac = createWebApplicationContext(rootContext);
    }
    if (!this.refreshEventReceived)
    {
        //4、刷新上下文(执行一些初始化)
        onRefresh(wac);
    }
    if (this.publishContext)
    {
        // Publish the context as a servlet context attribute.
        String attrName = getServletContextAttributeName();
        getServletContext()
            .setAttribute(attrName, wac);
        //省略部分代码
    }
    return wac;
}

从initWebApplicationContext()方法能够看出,通常假如ContextLoaderListener加载了上下文将作为根上下文(DispatcherServlet的父容器),最后调用了onRefresh()方法执行容器的一些初始化,这个方法由子类实现,来进行扩展。

DispatcherServlet实现了onRefresh()方法提供一些前端控制器相关的配置

public class DispatcherServlet extends FrameworkServlet
{
    //实现子类的onRefresh()方法,该方法委托为initStrategies()方法。
    @Override
    protected void onRefresh(ApplicationContext context)
    {
        initStrategies(context);
    }
    //初始化默认的Spring Web MVC框架使用的策略(如HandlerMapping)
    protected viod initStrategies(ApplicationContext context)
    {
        initMultipartResolver(context); //初始化上传文件解析器
        initLocaleResolver(context); //初始化本地解析器
        initThemeResolver(context); //初始化主题解析器
        initHandlerMapping(context);
        //初始化处理器映射器,将请求映射到处理器
        initHandlerAdapters(context); //初始化处理器适配器
        initHandlerExceptionResolver(context);
        //初始化处理器异常解析器,如果执行过程中遇到异常将交给HandlerExceptionResolver来解析
        initRequestToViewNameTranslator(context);
        //初始化请求到具体视图名称解析器
        initViewResolvers(context);
        //初始化视图解析器,通过ViewResolver解析逻辑视图名到具体视图实现
        initFlshMapManager(context); //初始化flash映射管理
    }
}

initStrategies方法将在WebApplicationContext初始化后自动执行,自动扫描上下文的Bean,依据名称或者是类型匹配的机制查找自定义组件。

假如没有找到,就会装配一套Spring的默认组件.在org.springframework.web.servlet路径下有一个DispatcherServlet.properties配置文件,这个文件指定了DispatcherServlet所使用的默认组件。

DispatcherServlet启动的时候,会进行需要的Web层Bean的配置,例如HandlerMapping、HandlerAdapter等,假如,没有配置,还会给我们提供默认的配置。

整个DispatcherServlet初始化的过程具体主要做了初始化Spring Web MVC使用的Web上下文,并且可能指定父容器为(ContextLoaderListener加载了根上下文)以及初始化DispatcherServlet使用的策略,如HandlerMapping、HandlerAdapter等这两件事情。

现在有很多人都想要成为java架构师,假如你想了解这方面的知识,那么请继续关注奇Q工具网来进行了解吧。

推荐阅读:

dispatcherservlet工作流程详解

dispatcherservlet特点是什么?有什么特点?

dispatcherservlet作用是什么?功能有哪些?