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.