Spring——Web应用中的IoC容器创建(WebApplicationContext根应用上下文的创建过程)
基于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的部分配置:
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
这段配置意为给Servlet新增一个监听器,这个监听器需要实现ServletContextListener接口,该接口中有两个方法:
- public interface ServletContextListener extends EventListener {
- public void contextInitialized(ServletContextEvent sce); //ServletContext初始化的时候执行此方法
- public void contextDestroyed(ServletContextEvent sce); //ServletContext销毁的时候执行此方法
- }
接着来看ContextLoaderListener:
- public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
- public ContextLoaderListener() {
- }
- public ContextLoaderListener(WebApplicationContext context) {
- super(context);
- }
- public void contextInitialized(ServletContextEvent event) {
- this.initWebApplicationContext(event.getServletContext());
- }
- public void contextDestroyed(ServletContextEvent event) {
- this.closeWebApplicationContext(event.getServletContext());
- ContextCleanupListener.cleanupAttributes(event.getServletContext());
- }
- }
从ContextLoaderListener可以看出WebApplicationContext的初始化实际上是由ContextListener完成的:public void initWebApplicationContext(ServletContext servletContext)
- public void initWebApplicationContext(ServletContext servletContext)
- ......
- if(this.context == null) {
- this.context = this.createWebApplicationContext(servletContext); //创建根上下文,在这之前会检查是否已经存在,如果存在则抛出IllegalStateExcpetion异常,跳到第22行
- }
- ......
- if(this.context instanceof ConfigurableWebApplicationContext) {
- ConfigurableWebApplicationContext err = (ConfigurableWebApplicationContext)this.context;
- if(!err.isActive()) {
- if(err.getParent() == null) {
- ApplicationContext elapsedTime = this.loadParentContext(servletContext);
- err.setParent(elapsedTime);
- }
- this.configureAndRefreshWebApplicationContext(err, servletContext); //ApplicationContext上下文创建好后对其进行赋值和初始化,跳到第31行
- }
- }
- //将WebApplicationContext根上下文绑定到Web应用程序的ServletContext上.
- servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
- .....
- return this.context;
- }
- protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
- Class contextClass = this.determineContextClass(sc); //判断使用什么样的类在Web容器中作为IoC容器,跳到第26行
- ......
- }
- protected Class<?> determineContextClass(ServletContext servletContext) {
- String contexClassName = servlet.getInitParameter(CONTEXT_CLASS_PARAM); //读取web.xml中的配置<context-param>contextClass</context-param>
- //如果配置了需要使用的CONTEXT_CLASS,那就是用这个class,如果没有额外的配置,就是用默认的ContextClass也就是XmlWebApplicationContext.
- }
- //设置IoC容器的参数,并通过refresh启动容器的初始化
- protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc){
- String configLocationParam;
- if(ObjectUtils.identityToString(wac).equals(wac.getId())) {
- configLocationParam = sc.getInitParameter("contextId");
- if(configLocationParam != null) {
- wac.setId(configLocationParam);
- } else {
- wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath()));
- }
- }
- wac.setServletContext(sc);
- configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM); //contextConfigLocation,Spring根应用上下文重要的配置文件,很多bean的定义等等
- ......
- wac.refresh(); //启动容器的初始化
- }
以上代码第27行所述web.xml中配置指定的IoC容器:
- <context-param>
- <param-name>contextClass</param-name>
- <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
- </context-param>
以上代码第42行所述web.xml中配置指定的IoC容器:
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath*:applicationContext.xml</param-value>
- </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根应用上下文的创建过程)的更多相关文章
- Spring学习(四)在Web项目中实例化IOC容器
1.前言 前面我们讲到Spring在普通JAVA项目中的一些使用.本文将介绍在普通的Web项目中如何实例化Spring IOC容器.按照一般的思路.如果在Web中实例化Ioc容器.这不得获取Conte ...
- Spring在非web应用中关闭IoC容器 (registerShutdownHook)
在基于web的ApplicationContext实现中,已有相应的实现来处理关闭web应用时恰当地关闭Spring IoC容器.但,如果你正在一个非web应用的环境下使用Spring的IoC容器,如 ...
- Spring源码分析专题 —— IOC容器启动过程(上篇)
声明 1.建议先阅读<Spring源码分析专题 -- 阅读指引> 2.强烈建议阅读过程中要参照调用过程图,每篇都有其对应的调用过程图 3.写文不易,转载请标明出处 前言 关于 IOC 容器 ...
- 目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的创建
目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的创建 通过上面的介绍我们知道利用HttpControllerSelector可以根据 ...
- 【spring源码分析】IOC容器初始化(总结)
前言:在经过前面十二篇文章的分析,对bean的加载流程大致梳理清楚了.因为内容过多,因此需要进行一个小总结. 经过前面十二篇文章的漫长分析,终于将xml配置文件中的bean,转换成我们实际所需要的真正 ...
- 【spring源码分析】IOC容器初始化(二)
前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...
- 【spring源码分析】IOC容器初始化(三)
前言:在[spring源码分析]IOC容器初始化(二)中已经得到了XML配置文件的Document实例,下面分析bean的注册过程. XmlBeanDefinitionReader#registerB ...
- 【spring源码分析】IOC容器初始化(四)
前言:在[spring源码分析]IOC容器初始化(三)中已经分析了BeanDefinition注册之前的一些准备工作,下面将进入BeanDefinition注册的核心流程. //DefaultBean ...
- 【spring源码分析】IOC容器初始化(七)
前言:在[spring源码分析]IOC容器初始化(六)中分析了从单例缓存中加载bean对象,由于篇幅原因其核心函数 FactoryBeanRegistrySupport#getObjectFromFa ...
随机推荐
- python实现mysql的读写分离及负载均衡
Oracle数据库有其公司开发的配套rac来实现负载均衡,目前已知的最大节点数能到128个,但是其带来的维护成本无疑是很高的,并且rac的稳定性也并不是特别理想,尤其是节点很多的时候. 但是,相对my ...
- D3.js-坐标轴生成测试SVG
Bottom top Bottom top // =0) return "translate("+margin+","+i*offset+")&q ...
- 面试题(一)—Java基础(上)
1.面向对象的三大特征 (1)封装 封装性指的是隐藏了对象的属性和实现细节,对外仅提供公共的访问方式. 好处: 将变化隔离,提供复用性和安全性. (2)继承 提高代码的复 ...
- Visual Studio中的TabControl控件的用法
今天遇到了一个自己没遇到过的控件TabControl控件,所以找了点关于它的资料 TabControl属性 DisplayRect:只定该控件客户区的一个矩形 HotTrack:设置当鼠标经过页标签 ...
- Cocos2d-x性能分析-Android版本之Gprof
在 iOS 平台下我们可以用 Xcode 自带的 Profile 工具来测试我们程序的性能,Android 平台使用的 gprof 这里整理了一下具体的cocos2dx 使用gprof进行性能分析的具 ...
- 运行第一个Docker容器
1. Docker介绍 Docker由dotCloud公司发起的一个内部项目,后来Docker火了,dotCloud公司改名为Docker了: Docker使用了Go语言开发,基于 Linux 内核的 ...
- Eclipse导入Android签名
本篇主要参照http://blog.csdn.net/wuxy_shenzhen/article/details/20946839 在安装安卓apk时经常会出现类似INSTALL_FAILED_SHA ...
- js的几大数据类型
一. js的几大数据类型 数字:浮点数(3.14)+整数(1): 字符串:包括由任意数量字符组成的序列,例如:'a','one': 布尔值:true+false: undefined:当我们试图访问一 ...
- Excception and Error
exception and error都是继承throwable类; Exception就是程序中出现的异常,程序会去捕获: 但是error是比较严重的错误,程序是不会去捕获的: erroe:一般都是 ...
- # Android动画笔记
标签: Android开发艺术探索笔记 View动画 帧动画 属性动画 View动画 View动画的作用对象时View,有4种动画效果,分别是平移动画.缩放动画.旋转动画.和透明度动画. 此类动画通常 ...