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

目录
相关文章
|
7月前
|
前端开发 Java 数据格式
【Spring系列笔记】定义Bean的方式
在Spring Boot应用程序中,定义Bean是非常常见的操作,它是构建应用程序的基础。Spring Boot提供了多种方式来定义Bean,每种方式都有其适用的场景和优势。
116 2
|
7月前
|
Java 容器 Spring
Javaweb之SpringBootWeb案例之 Bean管理的Bean作用域详细的解析
Javaweb之SpringBootWeb案例之 Bean管理的Bean作用域详细的解析
44 0
|
7月前
|
前端开发 Java 数据库
【Spring原理进阶】SpringMVC调用链+JSP模板应用讲解
【Spring原理进阶】SpringMVC调用链+JSP模板应用讲解
|
Java Spring
spring bean初始化过程
从这个简单的代码衍生,使用AnnotationConfigApplicationContext看一下spring bean的初始化过程
181 0
spring bean初始化过程
|
XML 存储 前端开发
一.SpringMVC源码剖析-SpringMVC初始化
SpringMVC是基于Spring功能之上添加的Web框架,是市场上最流行的MVC框架,Spring MVC 是基于 Servlet 功能实现的,通过 Servlet 接口的 DispatcherServlet 来封装其核心功能实现,通过将请求分派给处理程序,同时带有可配置的处理程序映射、视图解析、本地语言、主题解析以及上载文件支持。 在之前的《Spring源码剖析》系列文章中我们对Spring核心进行了分析,从这篇文章开始着手于SpringMVC源码分析。如果对你有所帮助,请使劲三连。
|
XML Java 数据格式
第四章 spring bean定义
第四章 spring bean定义
89 0
|
存储 Java Spring
Spring之Bean的生命周期源码解析(三 Bean的创建与销毁)
Spring之Bean的生命周期源码解析(三 Bean的创建与销毁)
235 0
|
存储 缓存 搜索推荐
Spring 源码学习(四) bean 的加载(上)
既然我们 Spring 辛辛苦苦将 bean 进行了注册,当然需要拿出来进行使用,在使用之前还需要经过一个步骤,就是 bean 的加载。 在第一篇笔记提到了,完成 bean 注册到 beanDefinitionMap 注册表后,还调用了很多后处理器的方法,其中有一个方法 finishBeanFactoryInitialization(),注释上面写着 Instantiateall remaining(non-lazy-init)singletons,意味着非延迟加载的类,将在这一步实例化,完成类的加载。 而我们使用到 context.getBean("beanName")方法,如果对应的
Spring 源码学习(四) bean 的加载(上)
|
Java 容器 Spring
一张图搞懂Spring bean的完整生命周期
一张图搞懂Spring bean的生命周期,从Spring容器启动到容器销毁bean的全过程,包括下面一系列的流程,了解这些流程对我们想在其中任何一个环节怎么操作bean的生成及修饰是非常有帮助的。
一张图搞懂Spring bean的完整生命周期
|
设计模式 XML 存储
Spring5参考指南:Bean作用域
Spring5参考指南:Bean作用域