基于Spring-4.3.7.RELEASE

Spring的配置不仅仅局限在XML文件,同样也可以使用Java代码来配置。在这里我使用XML配置文件的方式来粗略地讲讲WebApplicationContext。

一提到Spring,首先就应该能想到的是IoC和AOP,什么是IoC、AOP不在这里做讲解。Spring提供一个最为基础的IoC容器——BeanFactory,但这个IoC容器所能提供给我们的功能比较少,所以我们通常选用另一个——ApplicationContext(应用上下文)来作为我们的IoC容器,其实ApplicationContext也是继承自BeanFactory,只是在BeanFactory接口基础上做了扩展。那我们这篇文章里要提到的WebApplicationContext不难猜测出它是ApplicationContext的一个实现,在Web应用中我们就利用WebApplicationContext作为我们的IoC容器。

在Web应用中要使用Spring的IoC容器,首要问题就是如何将IoC容器加载到Web容器中。以下是web.xml的部分配置:

  1. <listener>
  2. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  3. </listener>

这段配置意为给Servlet新增一个监听器,这个监听器需要实现ServletContextListener接口,该接口中有两个方法:

  1. public interface ServletContextListener extends EventListener {
  2. public void contextInitialized(ServletContextEvent sce);  //ServletContext初始化的时候执行此方法
  3. public void contextDestroyed(ServletContextEvent sce);  //ServletContext销毁的时候执行此方法
  4. }

接着来看ContextLoaderListener:

  1. public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
  2. public ContextLoaderListener() {
  3. }
  4.  
  5. public ContextLoaderListener(WebApplicationContext context) {
  6. super(context);
  7. }
  8.  
  9. public void contextInitialized(ServletContextEvent event) {
  10. this.initWebApplicationContext(event.getServletContext());
  11. }
  12.  
  13. public void contextDestroyed(ServletContextEvent event) {
  14. this.closeWebApplicationContext(event.getServletContext());
  15. ContextCleanupListener.cleanupAttributes(event.getServletContext());
  16. }
  17. }

从ContextLoaderListener可以看出WebApplicationContext的初始化实际上是由ContextListener完成的:public void initWebApplicationContext(ServletContext servletContext)

  1. public void initWebApplicationContext(ServletContext servletContext)
  2. ......
  3. if(this.context == null) {
  4. this.context = this.createWebApplicationContext(servletContext); //创建根上下文,在这之前会检查是否已经存在,如果存在则抛出IllegalStateExcpetion异常,跳到第22行
  5. }
  6. ......
  7. if(this.context instanceof ConfigurableWebApplicationContext) {
  8. ConfigurableWebApplicationContext err = (ConfigurableWebApplicationContext)this.context;
  9. if(!err.isActive()) {
  10. if(err.getParent() == null) {
  11. ApplicationContext elapsedTime = this.loadParentContext(servletContext);
  12. err.setParent(elapsedTime);
  13. }
  14. this.configureAndRefreshWebApplicationContext(err, servletContext); //ApplicationContext上下文创建好后对其进行赋值和初始化,跳到第31行
  15. }
  16. }
  17. //将WebApplicationContext根上下文绑定到Web应用程序的ServletContext上.
  18. servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
  19. .....
  20. return this.context;
  21. }
  22. protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
  23. Class contextClass = this.determineContextClass(sc); //判断使用什么样的类在Web容器中作为IoC容器,跳到第26行
  24. ......
  25. }
  26. protected Class<?> determineContextClass(ServletContext servletContext) {
  27. String contexClassName = servlet.getInitParameter(CONTEXT_CLASS_PARAM); //读取web.xml中的配置<context-param>contextClass</context-param>
  28. //如果配置了需要使用的CONTEXT_CLASS,那就是用这个class,如果没有额外的配置,就是用默认的ContextClass也就是XmlWebApplicationContext.
  29. }
  30. //设置IoC容器的参数,并通过refresh启动容器的初始化
  31. protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc){
  32. String configLocationParam;
  33. if(ObjectUtils.identityToString(wac).equals(wac.getId())) {
  34. configLocationParam = sc.getInitParameter("contextId");
  35. if(configLocationParam != null) {
  36. wac.setId(configLocationParam);
  37. } else {
  38. wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath()));
  39. }
  40. }
  41. wac.setServletContext(sc);
  42. configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM); //contextConfigLocation,Spring根应用上下文重要的配置文件,很多bean的定义等等
  43. ......
  44. wac.refresh(); //启动容器的初始化
  45. }

以上代码第27行所述web.xml中配置指定的IoC容器:

  1. <context-param>
  2. <param-name>contextClass</param-name>
  3. <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
  4. </context-param>

以上代码第42行所述web.xml中配置指定的IoC容器:

  1. <context-param>
  2. <param-name>contextConfigLocation</param-name>
  3. <param-value>classpath*:applicationContext.xml</param-value>
  4. </context-param>

上面这段配置就是自定义要使用的IoC容器而不使用默认的XmlApplicationContext容器.

第7行代码开始,当ApplicationContext上下文建立起来过后,也就是Web应用中的IoC容器建立起来过后,接下来就是applicationContext设置一些参数例如它的双亲.至此在Web应用环境中的IoC容器就已经完成了初始化,由于要考虑Web容器的环境特别,比如各种参数的设置,所以在上面的代码能看出首先创建了IoC容器,其次再为容器赋一些参数值,最后还有IoC容器和Web容器SevletContext的结合作为全局应用上下文.在接下来会介绍在启动Spring MVC时DispatcherServert在进行自己持有的上下文的初始化时,将ApplicationContext根应用上下文设置为DispatcherServlet的双亲上下文.

Spring——Web应用中的IoC容器创建(WebApplicationContext根应用上下文的创建过程)的更多相关文章

  1. Spring学习(四)在Web项目中实例化IOC容器

    1.前言 前面我们讲到Spring在普通JAVA项目中的一些使用.本文将介绍在普通的Web项目中如何实例化Spring IOC容器.按照一般的思路.如果在Web中实例化Ioc容器.这不得获取Conte ...

  2. Spring在非web应用中关闭IoC容器 (registerShutdownHook)

    在基于web的ApplicationContext实现中,已有相应的实现来处理关闭web应用时恰当地关闭Spring IoC容器.但,如果你正在一个非web应用的环境下使用Spring的IoC容器,如 ...

  3. Spring源码分析专题 —— IOC容器启动过程(上篇)

    声明 1.建议先阅读<Spring源码分析专题 -- 阅读指引> 2.强烈建议阅读过程中要参照调用过程图,每篇都有其对应的调用过程图 3.写文不易,转载请标明出处 前言 关于 IOC 容器 ...

  4. 目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的创建

    目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的创建 通过上面的介绍我们知道利用HttpControllerSelector可以根据 ...

  5. 【spring源码分析】IOC容器初始化(总结)

    前言:在经过前面十二篇文章的分析,对bean的加载流程大致梳理清楚了.因为内容过多,因此需要进行一个小总结. 经过前面十二篇文章的漫长分析,终于将xml配置文件中的bean,转换成我们实际所需要的真正 ...

  6. 【spring源码分析】IOC容器初始化(二)

    前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...

  7. 【spring源码分析】IOC容器初始化(三)

    前言:在[spring源码分析]IOC容器初始化(二)中已经得到了XML配置文件的Document实例,下面分析bean的注册过程. XmlBeanDefinitionReader#registerB ...

  8. 【spring源码分析】IOC容器初始化(四)

    前言:在[spring源码分析]IOC容器初始化(三)中已经分析了BeanDefinition注册之前的一些准备工作,下面将进入BeanDefinition注册的核心流程. //DefaultBean ...

  9. 【spring源码分析】IOC容器初始化(七)

    前言:在[spring源码分析]IOC容器初始化(六)中分析了从单例缓存中加载bean对象,由于篇幅原因其核心函数 FactoryBeanRegistrySupport#getObjectFromFa ...

随机推荐

  1. python实现mysql的读写分离及负载均衡

    Oracle数据库有其公司开发的配套rac来实现负载均衡,目前已知的最大节点数能到128个,但是其带来的维护成本无疑是很高的,并且rac的稳定性也并不是特别理想,尤其是节点很多的时候. 但是,相对my ...

  2. D3.js-坐标轴生成测试SVG

    Bottom top Bottom top   // =0) return "translate("+margin+","+i*offset+")&q ...

  3. 面试题(一)—Java基础(上)

    1.面向对象的三大特征 (1)封装      封装性指的是隐藏了对象的属性和实现细节,对外仅提供公共的访问方式.      好处: 将变化隔离,提供复用性和安全性. (2)继承      提高代码的复 ...

  4. Visual Studio中的TabControl控件的用法

    今天遇到了一个自己没遇到过的控件TabControl控件,所以找了点关于它的资料 TabControl属性 DisplayRect:只定该控件客户区的一个矩形  HotTrack:设置当鼠标经过页标签 ...

  5. Cocos2d-x性能分析-Android版本之Gprof

    在 iOS 平台下我们可以用 Xcode 自带的 Profile 工具来测试我们程序的性能,Android 平台使用的 gprof 这里整理了一下具体的cocos2dx 使用gprof进行性能分析的具 ...

  6. 运行第一个Docker容器

    1. Docker介绍 Docker由dotCloud公司发起的一个内部项目,后来Docker火了,dotCloud公司改名为Docker了: Docker使用了Go语言开发,基于 Linux 内核的 ...

  7. Eclipse导入Android签名

    本篇主要参照http://blog.csdn.net/wuxy_shenzhen/article/details/20946839 在安装安卓apk时经常会出现类似INSTALL_FAILED_SHA ...

  8. js的几大数据类型

    一. js的几大数据类型 数字:浮点数(3.14)+整数(1): 字符串:包括由任意数量字符组成的序列,例如:'a','one': 布尔值:true+false: undefined:当我们试图访问一 ...

  9. Excception and Error

    exception and error都是继承throwable类; Exception就是程序中出现的异常,程序会去捕获: 但是error是比较严重的错误,程序是不会去捕获的: erroe:一般都是 ...

  10. # Android动画笔记

    标签: Android开发艺术探索笔记 View动画 帧动画 属性动画 View动画 View动画的作用对象时View,有4种动画效果,分别是平移动画.缩放动画.旋转动画.和透明度动画. 此类动画通常 ...