美文网首页
springmvc源码分析-容器初始化

springmvc源码分析-容器初始化

作者: hello_kd | 来源:发表于2021-04-10 09:36 被阅读0次

在前文知道了,DispatcherServlet的init方法是springmvc项目初始化的入口,init方法内部又调用了initServletBean

protected final void initServletBean() throws ServletException {
//省略
        try {
                    //初始化spring容器,在这里完成应用内bean的扫描和创建
            this.webApplicationContext = initWebApplicationContext();
                    //初始化servlet,默认空实现,由子类实现
            initFrameworkServlet();
        }
        catch (ServletException | RuntimeException ex) {
            logger.error("Context initialization failed", ex);
            throw ex;
        }
    }
//省略
protected WebApplicationContext initWebApplicationContext() {
    WebApplicationContext rootContext =
            WebApplicationContextUtils.getWebApplicationContext(getServletContext());
    WebApplicationContext wac = null;

    if (this.webApplicationContext != null) {
        wac = this.webApplicationContext;
        if (wac instanceof ConfigurableWebApplicationContext) {
            ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
            if (!cwac.isActive()) {
                if (cwac.getParent() == null) {
                    cwac.setParent(rootContext);
                }
//核心方法
                configureAndRefreshWebApplicationContext(cwac);
            }
        }
    }
    //省略.....
    if (this.publishContext) {
        // Publish the context as a servlet context attribute.
        String attrName = getServletContextAttributeName();
        getServletContext().setAttribute(attrName, wac);
    }

    return wac;
}

configureAndRefreshWebApplicationContext方法主要就是初始化context的一些成员属性,将servlet信息加入到spring容器,然后刷新容器

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
        //省略.....
//设置servletContext和servletConfig,这样在容器就可以使用这两个对象了
        wac.setServletContext(getServletContext());
        wac.setServletConfig(getServletConfig());
        wac.setNamespace(getNamespace());
//添加监听器,当spring容器完成创建并刷新时,会回调此观察者,
//这里很重要,因为DispatcherServlet的几个重要组件都是在回调方法里面进行处理和赋值的
        wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));

        //设置环境的propertyResource
        ConfigurableEnvironment env = wac.getEnvironment();
        if (env instanceof ConfigurableWebEnvironment) {
            ((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());
        }
//空实现,留给子类处理
        postProcessWebApplicationContext(wac);
//调用初始化器,在刷新容器之前,做一些初始化操作
        applyInitializers(wac);
//刷新容器,这里对刷新容器就不展开了,这个主要是spring的基础知识
        wac.refresh();
    }

当完成spring容器的刷新之后,ContextRefreshListener的回调方法便会收到通知

public void onApplicationEvent(ContextRefreshedEvent event) {
            FrameworkServlet.this.onApplicationEvent(event);
}

通过跟进FrameworkServlet的onApplicationEvent方法,可以看到springmvc几个重要组件的初始化

protected void initStrategies(ApplicationContext context) {
        initMultipartResolver(context);
        initLocaleResolver(context);
        initThemeResolver(context);
        initHandlerMappings(context);
        initHandlerAdapters(context);
        initHandlerExceptionResolvers(context);
        initRequestToViewNameTranslator(context);
        initViewResolvers(context);
        initFlashMapManager(context);
    }

整个springmvc的核心就是上述几个组件,这个后面再展开。当spring容器完成刷新并通知了观察者后,程序流程又回到了initWebApplicationContext

if (this.publishContext) {
            //将容器上下文对象添加到ServletContext中
            String attrName = getServletContextAttributeName();
            getServletContext().setAttribute(attrName, wac);
        }

至此,springmvc的初始化流程就走完了,也就是DispatcherServlet的init方法执行完毕。web应用启动了

相关文章

网友评论

      本文标题:springmvc源码分析-容器初始化

      本文链接:https://www.haomeiwen.com/subject/qvvgkltx.html