SpringMVC 第二章 - WebApplicationContext的初始化

简介: 上一篇章主要总结了SpringMVC在启动的时候,会去构造webApplicationContext对象,并且将该对象放入到ServletContext中,在web的整个生命周期中使用。在分析Spring MVC最重要的一个类DispatcherServlet的时候,在其父类初始化的时候,发现了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

目录
相关文章
|
5月前
|
Java 应用服务中间件 Maven
ContextLoaderListener在Spring应用中的作用与配置方法
ContextLoaderListener在Spring应用中的作用与配置方法
|
6月前
|
Java 容器 Spring
Javaweb之SpringBootWeb案例之 Bean管理的Bean作用域详细的解析
Javaweb之SpringBootWeb案例之 Bean管理的Bean作用域详细的解析
40 0
|
6月前
|
前端开发 Java 数据库
【Spring原理进阶】SpringMVC调用链+JSP模板应用讲解
【Spring原理进阶】SpringMVC调用链+JSP模板应用讲解
|
Java Spring
spring bean初始化过程
从这个简单的代码衍生,使用AnnotationConfigApplicationContext看一下spring bean的初始化过程
177 0
spring bean初始化过程
|
XML 存储 前端开发
一.SpringMVC源码剖析-SpringMVC初始化
SpringMVC是基于Spring功能之上添加的Web框架,是市场上最流行的MVC框架,Spring MVC 是基于 Servlet 功能实现的,通过 Servlet 接口的 DispatcherServlet 来封装其核心功能实现,通过将请求分派给处理程序,同时带有可配置的处理程序映射、视图解析、本地语言、主题解析以及上载文件支持。 在之前的《Spring源码剖析》系列文章中我们对Spring核心进行了分析,从这篇文章开始着手于SpringMVC源码分析。如果对你有所帮助,请使劲三连。
|
存储 Java 应用服务中间件
Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】(下)
前面我们已经学过了Servlet的生命周期了,我们根据Servlet的生命周期画出Servlet的调用图加深理解
144 0
Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】(下)
|
Java 应用服务中间件 数据库
Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】(中)
前面我们已经学过了Servlet的生命周期了,我们根据Servlet的生命周期画出Servlet的调用图加深理解
140 0
Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】(中)
|
开发框架 Java .NET
Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】(上)
前面我们已经学过了Servlet的生命周期了,我们根据Servlet的生命周期画出Servlet的调用图加深理解
120 0
Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】(上)
|
缓存 Java API
SpringMVC源码解析之RequestMappingHandlerAdapter(上))
SpringMVC源码解析之RequestMappingHandlerAdapter(上))
206 0
SpringMVC源码解析之RequestMappingHandlerAdapter(上))
|
Web App开发 存储 Java
Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】
Servlet的调用图 前面我们已经学过了Servlet的生命周期了,我们根据Servlet的生命周期画出Servlet的调用图加深理解 Servlet的细节 一个已经注册的Servlet可以被多次映射 同一个Servlet可以被映射到多个URL上。
1146 0