1.什么叫beanfactory?
spring使用BeanFactory来实例化、配置和管理对象,但是它只是一个接口,里面有一个getBean()方法。我们一般都不直接用BeanFactory,而是用它的实现类ApplicationContext,这个类会自动解析我们配置的applicationContext.xml,然后根据我们配置的bean来new对象,将new好的对象放进一个Map中,键就是我们bean的id,值就是new的对象。
原文参考http://www.cnblogs.com/liuling/archive/2013/04/14/BeanFactory.html
2.什么叫ApplicationContext?
答:实用的Bean工厂ApplicationContext,继承BeanFactory接口
在ApplicationContext接口的众多实现类中,有3个是我们经常用到的(见表1-1),并且使用这3个实现类也基本能满足我们Java EE应用开发中的绝大部分需求。
表1-1 ApplicationContext接口的常用实现类介绍
类 名 称 |
功 能 描 述 |
ClassPathXmlApplicationContext |
从类路径ClassPath中寻找指定的XML配置文件,找到并装载 完成ApplicationContext的实例化工作。例如: //装载单个配置文件实例化ApplicationContext容器 ApplicationContext cxt = new ClassPathXmlApplicationContext ("applicationContext.xml"); //装载多个配置文件实例化ApplicationContext容器 String[] configs = {"bean1.xml","bean2.xml","bean3.xml"}; ApplicationContext cxt = new ClassPathXmlApplicationContext(configs); |
FileSystemXmlApplicationContext |
从指定的文件系统路径中寻找指定的XML配置文件,找到并装载 完成ApplicationContext的实例化工作。例如: //装载单个配置文件实例化ApplicationContext容器 ApplicationContext cxt = new FileSystemXMLApplicationContext ("beans.xml"); //装载多个配置文件实例化ApplicationContext容器 String[] configs = {"c:/beans1.xml","c:/beans2.xml"}; ApplicationContext cxt = new FileSystemXmlApplicationContext(configs); |
XmlWebApplicationContext |
从Web应用中的寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作。这是为Web工程量身定制的,使用WebApplicationContextUtils类的getRequiredWebApplicationContext方法可在JSP与Servlet中取得IoC容器的引用 |
3.applicationContext与beanFactory的不同?
与BeanFactory不同的是,ApplicationContext容器实例化后会自动对所有的单实例Bean进行实例化与依赖关系的装配,使之处于待用状态。而BeanFactory容器实例化后并不会自动实例化Bean,只有当Bean被使用时BeanFactory容器才会对该Bean进行实例化与依赖关系的装配。
在Java项目中通过ClassPathXmlApplicationContext类手动实例化ApplicationContext容器通常是不二之选。但对于Web项目就不行了,Web项目的启动是由相应的Web服务器负责的,因此,在Web项目中ApplicationContext容器的实例化工作最好交给Web服务器来完成。
4.在web项目中,怎样实例化applicationContext?
答:
Spring为此提供了两种解决方案,一种是基于ContextLoaderListener实现的(此方案只适用于Servlet2.4及以上规范的Servlet容器)。例如,在web.xml中加入如下代码:
<!-- 指定Spring的配置文件,多个配置文件以逗号分隔 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-config/applicationContext.xml</param-value>
</context-param>
<!-- 指定以Listener方式启动Spring容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
另外一种方案则是基于ContextLoaderServlet实现的。例如,在web.xml中加入如下代码:
<!-- 指定Spring的配置文件,多个配置文件以逗号分隔 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-config/applicationContext.xml</param-value>
</context-param>
<!-- 指定以Servlet方式启动Spring容器 -->
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
从servlet容器启动时加载组件的顺序来看,Listener组件是优先于Servlet组件的。基于Servlet方式的加载方案主要是为了兼容Servlet2.3及以下规范的Servlet容器。以Tomcat为例,Tomcat 5.x都已经支持Servlet2.4规范了,因此,基于Listener方式启动Spring容器是目前的主流选择。
5.web开发选择哪种方式实例化applicationConntext比较好?
答:从servlet容器启动时加载组件的顺序来看,Listener组件是优先于Servlet组件的。因此,基于Listener方式启动Spring容器是目前的主流选择。
本文主要参考:http://baike.baidu.com/link?url=Ll-tgSO20TwrB6sm7Eu9RKtaZuxb-hwazwqg-53kwlkPynRPwdF27bX6kOgEzq6vHiXv8dwj7xqRw9v0IsSKINnn__SFKp_XOcsvWPYvuqy
6.spring的上下文和spring mvc的上下文和web应用的上下文之间有什么关系?
答:
要想很好理解这三个上下文的关系,需要先熟悉spring是怎样在web容器中启动起来的。spring的启动过程其实就是其IoC容器的启动过程,对于web程序,IoC容器启动过程即是建立上下文的过程。
spring的启动过程:
- 首先,对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环境;
- 其次,在web.xml中会提供有contextLoaderListener。在web容器启动时,会触发容器初始化事件,此时contextLoaderListener会监听到这个事件,其contextInitialized方法会被调用,在这个方法中,spring会初始化一个启动上下文,这个上下文被称为根上下文,即WebApplicationContext,这是一个接口类,确切的说,其实际的实现类是XmlWebApplicationContext。这个就是spring的IoC容器,其对应的Bean定义的配置由web.xml中的context-param标签指定。在这个IoC容器初始化完毕后,spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,便于获取;
- 再次,contextLoaderListener监听器初始化完毕后,开始初始化web.xml中配置的Servlet,这个servlet可以配置多个,以最常见的DispatcherServlet为例,这个servlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。DispatcherServlet上下文在初始化的时候会建立自己的IoC上下文,用以持有spring mvc相关的bean。在建立DispatcherServlet自己的IoC上下文时,会利用WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE先从ServletContext中获取之前的根上下文(即WebApplicationContext)作为自己上下文的parent上下文。有了这个parent上下文之后,再初始化自己持有的上下文。这个DispatcherServlet初始化自己上下文的工作在其initStrategies方法中可以看到,大概的工作就是初始化处理器映射、视图解析等。这个servlet自己持有的上下文默认实现类也是mlWebApplicationContext。初始化完毕后,spring以与servlet的名字相关(此处不是简单的以servlet名为Key,而是通过一些转换,具体可自行查看源码)的属性为属性Key,也将其存到ServletContext中,以便后续使用。这样每个servlet就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的bean,即根上下文(第2步中初始化的上下文)定义的那些bean。
说完了spring上下文的初始化过程,这三个上下文的关系应该就了解了。如还是不太清楚,我就爱莫能助了,只能自行看代码去了。
转自https://segmentfault.com/q/1010000000210417 感谢作者