7.4.2 使用ApplicationContext
7.4.2 使用ApplicationContext
大部分时候,都不会使用BeanFactory
实例作为Spring
容器,而是使用ApplicationContext
实例作为容器,因此Spring
容器也称为Spring
上下文。 ApplicationContext
作为BeanFactory
的子接口,增强了BeanFactory
的功能。ApplicationContext
允许以声明式方式操作容器,无须手动创建它。可利用如ContextLoader
的支持类,在Web
应用启动时自动创建ApplicationContext
。当然也可采用编程方式创建ApplicationContext
.
ApplicationContext额外功能
除了提供BeanFactory
所支持的全部功能外, ApplicationContext
还有如下额外的功能。
ApplicationContext
默认会预初始化所有的singleton Bean
,也可通过配置取消预初始化ApplicationContext
继承MessageSource
接口,因此提供国际化支持。- 资源访问,比如访问
URL
和文件。 - 事件机制。
- 同时加载多个配置文件。
- 以声明式方式启动并创建
Spring
容器。
ApplicationContext
包括BeanFactory
的全部功能,因此建议优先使用ApplicationContext
。除非对于某些内存非常关键的应用,才考虑使用BeanFactory
.
程序示例
项目结构
例如有如下配置。
beans.xml
1 |
|
上面粗体字代码配置了一个id
为chinese
的bean
,如果没有任何特殊配置,该Bean
就是singleton Bean
,ApplicationContext
会在容器初始化完成后,自动调用Person
类的构造器创建chinese
这个Bean
,并以"孙悟空"
这个字符串作为传入参数去调用chinese
这个bean
的setTest
方法。
Person.java
该程序用的Person
类的代码如下。
1 | package org.crazyit.app.service; |
测试
即使主程序只有如下一行代码:
1 | ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); |
上面代码只是使用ApplicationContext
创建了Spring
容器, ApplicationContext
会自动预初始化容器中的chinese
这个bean
包括:
- 调用它的无参数的构造器,
- 根据
< property.>
元素执行setter
方法。
执行上面代码,可以看到如下输出:
1 | ==正在执行Person无参数的构造器== |
如果将main
方法中创建Spring
容器的代码换成使用BeanFactory
作为容器,例如改为如下代码:
1 | // 搜索类加载路径下的beans.xml文件创建Resource对象 |
上面代码以BeanFactory
创建了Spring
容器,但**BeanFactory
不会预初始化容器中的Bean
**,因此执行上面代码不会看到调用Person
类的构造器、执行chinese
这个bean
的setName
方法。
如何阻止Spring容器预初始化Bean
为了阻止Spring
容器预初始化容器中的singleton Bean
,可以**为<bean>
元素指定lazy-init="true"
属性,该属性用于阻止容器预初始化该Bean
**。因此,如果为上面<bean>
元素指定了lazy-init="true"
,那么即使使用ApplicationContext
作为Spring
容器, Spring
也不会预初始化该singleton Bean
.