SpringMVC 第二章 - WebApplicationContext的初始化

    xiaoxiao2021-04-16  281

    上一篇章主要总结了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


    最新回复(0)