一、使用ApplicationContext

前面介绍了,我们一般不会使用BeanFactory实例作为Spring容器,而是使用ApplicationContext实例作为容器,它增强了BeanFactory的功能。

ApplicationContext允许以声明式方式操作容器,无须手动创建它。在Web应用启动时自动创建ApplicationContext。当然,也可以采用编程方式创建ApplicationContext。

除了提供BeanFactory所支持的全部功能外,ApplicationContext还有如下功能:

1、  ApplicationContext继承MessageSource接口,因此提供国际化支持。

2、  资源访问。

3、  事件机制。

4、  载入多个配置文件。

5、  以声明式的方式启动,并创建Spring容器。

当系统创建ApplicationContext容器时,默认会预初始化所有的singleton Bean。也就是说,当ApplicationContext容器初始化完成后,容器中所有singleton Bean也实例化完成,这就意味着:系统前期创建ApplicationContext时将有较大的系统开销,但一旦ApplicationContext初始化完成,程序后面获取singleton Bean实例时将拥有较好的性能。

二、ApplicationContext的国际化支持

ApplicationContext接口继承MessageSource接口,因此具备国际化功能。MessageSource接口中定义了三个方法用于国际化功能。

String getMessage(Stringcode,Object[] args,Locale loc);

StringgetMessage(String code,Object[] args,String default,Locale loc);

StringgetMessage(MessageSourceResolvable resolvable,Local loc);

ApplicationContext正是通过这三个方法来实现国际化的。当程序创建ApplicationContext容器时,Spring会自动查找在配置文件中名为messageSource的bean实例,一旦找到这个Bean实例,上述三个方法的调用被委托给该MessageSource Bean。如果没有该Bean,ApplicationContext会查找其父定义中的messagesource Bean,如果找到,它会作为messageSource Bean使用。但是如果无法找到messageSource,系统将会创建一个空的staticMessageSource Bean,该Bean的能接受上述三个方法的调用。

在Spring中配置messagesourceBean时通常使用ResourceBundleMessageSource.如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns="http://www.springframework.org/schema/beans"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
  6. <bean id="messsageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
  7. <property name="basenames">
  8. <list>
  9. <value>.....</value>
  10. <value>.....</value>
  11. <value>.....</value>
  12. </list>
  13. </property>
  14. </bean>
  15. </beans>

三、ApplicationContext的事件机制

ApplicationContext的事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext的事件处理。如果容器中有一个ApplicationListener Bean,每当ApplicationContext发布          ApplicationEvent时,ApplicationListenerBean就会自动触发。

Spring的事件框架有如下两个重要成员:

1、 ApplicationEvent:容器事件,必须由ApplicationContext发布。

2、 ApplicationListener:监听器,可由容器中的任何监听器Bean担任。

Spring的事件机制需要事件源、事件和事件监听器组成。只是此处的事件是ApplicationContext,且事件必须由java程序显示触发。下图简单示范了ApplicationContext的事件流程。

下面实例展示了Spring容器的事件机制。

1)、定义一个ApplicationEvent类,其对象就是Spring容器事件。

  1. <span style="font-family:Arial;">public class EmailEvent extends ApplicationEvent {
  2. private static final long serialVersionUID = 1L;
  3. private String address;
  4. private String text;
  5. // 定义一个带参的构造函数
  6. public EmailEvent(Object source) {
  7. super(source);
  8. }
  9. public EmailEvent(Object source, String address, String text) {
  10. super(source);
  11. this.address = address;
  12. this.text = text;
  13. }
  14. public String getAddress() {
  15. return address;
  16. }
  17. public void setAddress(String address) {
  18. this.address = address;
  19. }
  20. public String getText() {
  21. return text;
  22. }
  23. public void setText(String text) {
  24. this.text = text;
  25. }
  26. }</span>

容器事件的监听器类必须实现ApplicationListener接口,它的实现方法如下:

onAPplicationEvent(ApplicationEventevent):每当容器内发生任何事件时,此方法都会被触发。

2)、编写该容器的监听器类。

  1. public class EmailNotifier implements ApplicationListener{
  2. //该方法会在容器发生事件时触发
  3. public void onApplicationEvent(ApplicationEvent event) {
  4. if(event instanceof EmailEvent){
  5. //只处理EmailEvent,发送email通知
  6. EmailEvent emailEvent = (EmailEvent) event;
  7. System.out.println("需要发送邮件的接收地址为:"+emailEvent.getAddress());
  8. System.out.println("需要发送邮件的邮件正文是:"+emailEvent.getText());
  9. }
  10. else {
  11. //容器内置事件不作任何处理
  12. System.out.println("容器本身的事件:"+event);
  13. }
  14. }
  15. }

3)、将监听器类配置在容器中。

在为Spring容器注册监听器时,我们只需在Spring配置文件中配置一个实现了ApplicationListener的Bean即可,Spring容器会把这个Bean当做容器事件的监听器。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns="http://www.springframework.org/schema/beans"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
  6. <!-- 配置监听器 -->
  7. <bean class="com.app.listener.EmailNotifier"/>
  8. </beans>

通过上面的3个步骤就可以实现Spring容器的事件了。当系统创建Spring容器,加载Spring容器时会自动触发容器事件,容器事件监听器可以监听到这些事件。同时我们也可以调用ApplicationContext的pulishEvent()方法来主动触发容器事件。

  1. public class SpringTest {
  2. public static void main(String[] args) {
  3. ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
  4. //创建一个ApplicationEvent对象
  5. EmailEvent emailEvent = new EmailEvent("hell","spring_test@163.com","this is a test");
  6. //主动触发容器事件
  7. ctx.publishEvent(emailEvent);
  8. }
  9. }

如果Bean想发布事件,则Bean必须获得其容器的引用。如果程序中没有直接获取容器的引用,则应该让Bean实现ApplicationContextAware或BeanFactoryAware接口,从而获得容器的引用。

除了我们可以自己实现Spring容器的事件外,Spring也提供了几个内置事件:

1、  ContextRefreshedEvent:ApplicationContext容器初始化或者刷新时触发该事件。

2、  ContextStartedEvent:当使用ConfigurableApplicationContext接口的start()方法启动ApplicationContext容器时触发该事件。

3、  ContextClosedEvent:当使用ConfigurableApplicationContext接口的close()方法关闭ApplicationContext容器时触发该事件。

4、  ContextStopedEvent: 当使用ConfigurableApplicationContext接口的stop()方法停止ApplicationContext容器时触发该事件。

Spring读书笔记-----使用Spring容器(二)的更多相关文章

  1. Spring 读书笔记-----使用Spring容器(一)

    pring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口.他们都可代表Spring容器,Spri ...

  2. (转)Spring 读书笔记-----使用Spring容器(一)

    Spring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口.他们都可代表Spring容器,Spr ...

  3. (转)Spring读书笔记-----使用Spring容器(二)

    一.使用ApplicationContext 前面介绍了,我们一般不会使用BeanFactory实例作为Spring容器,而是使用ApplicationContext实例作为容器,它增强了BeanFa ...

  4. Spring读书笔记——bean创建(上)

    通过<Spring读书笔记--bean加载>和<Spring读书笔记--bean解析>,我们明白了两件事. Spring如何加载消化一个xml配置文件 Spring如何将xml ...

  5. Spring读书笔记——bean创建(下)

    有关Spring加载bean系列,今天这是最后一篇了,主要接上篇对于从Spring容器中获取Bean的一些细节实现的补充. <Spring读书笔记--bean加载>--Spring如何加载 ...

  6. (转) Spring读书笔记-----Spring的Bean之配置依赖

    前一篇博客介绍了Spring中的Bean的基本概念和作用域(Spring读书笔记-----Spring的Bean之Bean的基本概念),现在介绍Spring Bean的基本配置. 从开始我们知道Jav ...

  7. Spring读书笔记——bean解析

    前情回顾 上篇<Spring读书笔记--bean加载>我们从代码角度介绍了有哪些类负责解析XML文件,又是如何一步步从XML格式脱变成我们熟悉的bean的,直到DefaultBeanDef ...

  8. Spring读书笔记-----Spring的Bean之Bean的基本概念

    从前面我们知道Spring其实就是一个大型的工厂,而Spring容器中的Bean就是该工厂的产品.对于Spring容器能够生产那些产品,则取决于配置文件中配置. 对于我们而言,我们使用Spring框架 ...

  9. (转)Spring读书笔记-----Spring的Bean之Bean的基本概念

    从前面我们知道Spring其实就是一个大型的工厂,而Spring容器中的Bean就是该工厂的产品.对于Spring容器能够生产那些产品,则取决于配置文件中配置. 对于我们而言,我们使用Spring框架 ...

随机推荐

  1. 面向生产环境的大集群模式安装Hadoop

    一.实验说明 1.本实验将使用DNS而不是hosts文件解析主机名: 2.使用NFS共享密钥文件,而不是逐个手工拷贝添加密钥: 3.复制Hadoop时使用批量拷贝脚本而不是逐台复制. 测试环境: Ho ...

  2. [PHP100] PHP如何防止注入及开发安全

    1.PHP注入的基本原理 程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对 用户输入数据的合法性进行判断,使应用程序存在安全隐患.用户可以提交一段数据 库查询代码,根据程序返回 ...

  3. Javascript页面之间参数传递 (前端)

    一.来源:tongfang [系统管理员] --[系统管理] 的"SysLeftNavView.ascx.cs 用户插件 usercontrol 左侧菜单导航: <li>< ...

  4. AtomicInteger类保证线程安全的用法

    J2SE 5.0提供了一组atomic class来帮助我们简化同步处理.基本工作原理是使用了同步synchronized的方法实现了对一个long, integer, 对象的增.减.赋值(更新)操作 ...

  5. #ifdef __cplusplus extern "C" { #endif

    1.在好多程序中我们会遇到下面代码段 #ifdef __cplusplus        extern "C" {        #endif //c语法代码段 #ifdef __ ...

  6. C#中求数组的子数组之和的最大值

    <编程之美>183页,问题2.14——求子数组的字数组之和的最大值.(整数数组) 我开始以为可以从数组中随意抽调元素组成子数组,于是就有了一种想法,把最大的元素抽出来,判断是大于0还是小于 ...

  7. tensor

    初始化 z = torch.Tensor(,,,,) --可以创建多维数组.里面是随机的数. s = torch.Tensor(,):fill() --用1填充 t = torch.rand(,) m ...

  8. js 数组排序和算法排序

    1.算法排序 a.插入排序 var arr = [23,34,3,4,23,44,333,444]; var arrShow = (function insertionSort(array){ if( ...

  9. php 基础复习(2)GD库

    一,生成验证码: 1.生成一张图片: recource imagecreatetruecolor(int $width , int $height)  注意:提前输出图片的header信息,默认是黑色 ...

  10. python学习笔记四 迭代器,生成器,装饰器(基础篇)

    迭代器 __iter__方法返回一个迭代器,它是具有__next__方法的对象.在调用__next__方法时,迭代器会返回它的下一个值,若__next__方法调用迭代器 没有值返回,就会引发一个Sto ...