閱讀309 返回首頁    go 京東網上商城


SpringMVC 第二章 - WebApplicationContext的初始化

上一篇章主要總結了SpringMVC在啟動的時候,會去構造webApplicationContext對象,並且將該對象放入到ServletContext中,在web的整個生命周期中使用。在分析Spring MVC最重要的一個類DispatcherServlet的時候,在其父類初始化的時候,發現了webApplicationContext的初始化的方法,因此在這邊總結一下。

 /**
   *  webApplicationContext的初始化
   */
    protected WebApplicationContext initWebApplicationContext() {

        WebApplicationContext rootContext =  WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        WebApplicationContext wac = null;

        // Step1 : 通過構造函數的注入進行初始化
        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);
                }
            }
        }

        // Step2: 通過contextAttribute進行初始化
        if (wac == null) {
            wac = findWebApplicationContext();
        }

        // Step3: 重新創建webApplicationContext實例
        if (wac == null) {
            wac = createWebApplicationContext(rootContext);
        }

        if (!this.refreshEventReceived) {
            onRefresh(wac);
        }

        if (this.publishContext) {
            String attrName = getServletContextAttributeName();
            getServletContext().setAttribute(attrName, wac);
        }

        return wac;
    }

上麵這份源碼無非是在說明webApplicationContext是如何被構造的,默認還是使用反射的方式構建xmlWebApplicationContext實體類


  無論是通過構造函數注入還是單獨創建,到最後都會對已經創建的webApplicationContext實例進行配置以及刷新
 protected void initStrategies(ApplicationContext context) {
        initMultipartResolver(context);  # 上傳
        initLocaleResolver(context);      #  國際化語言
        initThemeResolver(context);      #  頁麵主題(靜態文件)
        initHandlerMappings(context);  #  初始化HandlerMappings (負責請求關係的轉發)        
        initHandlerAdapters(context);
        initHandlerExceptionResolvers(context);
        initRequestToViewNameTranslator(context);
        initViewResolvers(context);
        initFlashMapManager(context);
    }

我這邊隻對比較感興趣的initHandlerMappings(context) 和 initHandlerAdapters(context) 做解讀。

initHandlerMappings(context)

      當客戶端發出Request時,DispatcherServlet會將Request提交給HandlerMapping,然後HandlerMapping根據WebApplicationContext的配置來回傳給DispatcherServlet相應的Controller
      默認情況下,SpringMVC會加載當前係統中所有實現了HandlerMapping接口的Bean

 private void initHandlerMappings(ApplicationContext context) {
        this.handlerMappings = null;

        if (this.detectAllHandlerMappings) {
            Map<String, HandlerMapping> matchingBeans =  BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
            if (!matchingBeans.isEmpty()) {
                this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
                AnnotationAwareOrderComparator.sort(this.handlerMappings);
            }
        } else {
            try {
                HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
                this.handlerMappings = Collections.singletonList(hm);
            } catch (NoSuchBeanDefinitionException ex) {

            }
        }

        if (this.handlerMappings == null) {
            this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
        }
    }

initHandlerAdapters(context) 這個方法與上麵的方法類似,獲取適配器,Spring默認配置了3個適配器
(1)http請求處理器適配器:HttpRequestHandlerAdapter
(2)簡單控製器處理器適配器:SimpleControllerHandlerAdapter
(3)注解方法處理器適配器:AnnotationMethodHandlerAdapter

最後更新:2017-08-22 23:32:47

  上一篇:go  (轉載)程序員整理的各種不錯的工具
  下一篇:go  使用CopyTable同步HBase數據