阅读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数据