莫辂技术
今天是:
我需要三件东西:爱情友谊和图书。然而这三者之间何其相通!炽热的爱情可以充实图书的内容,图书又是人们最忠实的朋友。
User Image SpringMVC加载过程及原理 2018-11-02

1.springMvc 核心类DispathcerServlet 类继承关系

2.对于web.xml的加载过程一次是context-param > listener > fileter > servlet**,由于DispathcerServlet是一个Servelet 容器将执行标准的Servelet初始化

  1. GenericServlet中的初始化方法init将会运行,由于子类(HttpServletBean)实现了初始化方法,根据父子类的初始化关系,所以将会执行HttpServletBean中的init方法,该方法主要代码如下:
    public final void init() throws ServletException {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Initializing servlet '" + this.getServletName() + "'");
        }
    
        try {
            PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties);
            BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
            ResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext());
            bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment()));
            this.initBeanWrapper(bw);
            bw.setPropertyValues(pvs, true);
        } catch (BeansException var4) {
            this.logger.error("Failed to set bean properties on servlet '" + this.getServletName() + "'", var4);
            throw var4;
        }
    
        this.initServletBean();
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Servlet '" + this.getServletName() + "' configured successfully");
        }
    
    }
    可以看到里面将会加载web中配置的初始化参数和配置文件,然后执行 this.initServletBean();方法。
  2. initServletBean()是个空方法,子类FrameworkServlet重写了,将执行FrameworkServlet的initServletBean方法,该方法如下:

    protected final void initServletBean() throws ServletException {
        this.getServletContext().log("Initializing Spring FrameworkServlet '" + this.getServletName() + "'");
        if (this.logger.isInfoEnabled()) {
            this.logger.info("FrameworkServlet '" + this.getServletName() + "': initialization started");
        }
    
        long startTime = System.currentTimeMillis();
    
        try {
            this.webApplicationContext = this.initWebApplicationContext();
            this.initFrameworkServlet();
        } catch (ServletException var5) {
            this.logger.error("Context initialization failed", var5);
            throw var5;
        } catch (RuntimeException var6) {
            this.logger.error("Context initialization failed", var6);
            throw var6;
        }
    
        if (this.logger.isInfoEnabled()) {
            long elapsedTime = System.currentTimeMillis() - startTime;
            this.logger.info("FrameworkServlet '" + this.getServletName() + "': initialization completed in " + elapsedTime + " ms");
        }
    
    }
    这里初始化了webApplicationContext,initWebApplicationContext()方法是重点
    
    protected WebApplicationContext initWebApplicationContext() {
        WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.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);
                    }
    
                    this.configureAndRefreshWebApplicationContext(cwac);
                }
            }
        }
    
        if (wac == null) {
            wac = this.findWebApplicationContext();
        }
    
        if (wac == null) {
            wac = this.createWebApplicationContext(rootContext);
        }
    
        if (!this.refreshEventReceived) {
            this.onRefresh(wac);
        }
    
        if (this.publishContext) {
            String attrName = this.getServletContextAttributeName();
            this.getServletContext().setAttribute(attrName, wac);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Published WebApplicationContext of servlet '" + this.getServletName() + "' as ServletContext attribute with name [" + attrName + "]");
            }
        }
    
        return wac;
    }
    简单的逻辑是如果有WebApplicationContext这个对象,就配置刷新,如果没有创建,两者都会执行configureAndRefreshWebApplicationContext方法,然后执行refresh(); 该方法在AbstractApplicationContext中的实现如下;
    
    public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);
    
            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }
    
                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }
    
        }
  3. 继续完成一些初始化信息,里面有个onRefresh方法,接下来Dispatcher中onRefresh将会执行

    protected void onRefresh(ApplicationContext context) {
        this.initStrategies(context);
    }
    
    protected void initStrategies(ApplicationContext context) {
        this.initMultipartResolver(context);
        this.initLocaleResolver(context);
        this.initThemeResolver(context);
        this.initHandlerMappings(context);
        this.initHandlerAdapters(context);
        this.initHandlerExceptionResolvers(context);
        this.initRequestToViewNameTranslator(context);
        this.initViewResolvers(context);
        this.initFlashMapManager(context);
    }
    里面初始化视图解析器,处理器映射器等。至此,web容器初始化完成。

 

 

45 likes - 2 comments

我的

类型标签

外部链接

网站访问总量