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

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

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

  》ApplicationListener: 监听器,可有容器中的任何监听器Bean担任

  实际上,Spring 的事件机制与所有的事件机制都基本类似,他们都需要 事件源, 事件 和事件监听器 组成。只是此处的事件源是ApplicationContext。

  下图简单示范了ApplicationContext事件

  

  下面的程序僵尸翻生Spring容器的事件程序 。程序先定义了一个ApplicationContext类,其对象就是一个Spring容器事件。代码如下:

 import org.springframework.context.ApplicationEvent;

 public class EmailEvent extends ApplicationEvent{

     private static final long serialVersionUID = -7056841418193254583L;

     private String address;
private String text;
public EmailEvent(Object source) {
super(source);
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
} }

  上面的EmailEvent类继承了ApplicationContext类,除此之外,它就是一个普通的Java类。

  容器的监听器必须实现ApplicationListener接口,实现该接口必须实现如下方法:

  》onApplicationEvent(ApplicationEvent event):每当容器内发生任何事件时,此方法都被触发。

  本例所用的监听器代码如下:

 import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener; public class EmailNotifier implements ApplicationListener<ApplicationEvent>{ //该方法会在容器发生事件时自动触发
public void onApplicationEvent(ApplicationEvent event) {
if(event instanceof EmailEvent){
//只处理EmailEvent,发送Email通知...
EmailEvent emailEvent = (EmailEvent)event;
System.out.println("需要发送的邮件的接收地址:"+emailEvent.getAddress());
System.out.println("需要发送邮件的邮件正文:"+emailEvent.getText());
}else{
//容器内置时间不做任何处理
System.out.println("容器本身事件: "+event);
}
} }

  将监听器配置在容器中,配置文件如下:

 <?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- 配置监听器 -->
<bean class="com.spring_example.event.EmailNotifier" />
</beans>

  从上面的配置文件中可以看出,为Spring容器注册事件监听器,不需要像AWT编程那样采用代码进行编程,只要进行简单的配置即可。当我们在Spring配置了一个实现ApplicationListener的Bean。Springl容器就会把这个Bean当初容器的监听器。

  当系统创建Spring容器,加载Spring容器时会自动触发容器事件,容器事件监听器可以监听到这些事件。除此之外,程序也可调用ApplicationContext的publishEvent方法来主动触发容器事件。如下主程序使用ApplicationContext的publishEvent来触发事件。

         ApplicationContext ac = new ClassPathXmlApplicationContext("/applicationContext.xml");
//创建一个ApplicationEvent对象
EmailEvent ele = new EmailEvent("Hello");
ele.setAddress("123456@163.com");
ele.setText("Hello World");
//主动触发容器事件
ac.publishEvent(ele);

  上面的代码通过ApplicationContext对象的publishEvent主动触发该事件。运行上面的程序将看到如下执行结果。

 容器本身事件: org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.support.ClassPathXmlApplicationContext@141b571: startup date [Fri Sep 13 10:16:01 CST 2013]; root of context hierarchy]
需要发送的邮件的接收地址:123456@163.com
需要发送邮件的邮件正文:Hello World

  从上面的执行结果可以看出,监听器不仅监听到程序所触发的事件,也监听到容器内置的事件。实际上,如果开发者需要在Spring容器初始化,销毁时回调自定义方法,就可以通过上面的监听器来实现。

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

  Spring提供如下几个内置事件:

  》ContextRefreshEvent: ApplicationContext容器初始化或刷新触发该事件。此处的初始化是指,所有Bean 被成功装载,后处理Bean被检测并激发,所有Singleton Bean被预实例化,ApplicationContext容器已就绪可用。

  》ContextStartedEvent: 当使用ConfigurableApplicationContext(ApplicationContext的子接口)接口的start()方法启动ApplicationContext容器时触发该事件。容器管理生命周期的Bean实例将获得一个指定的启动信号,这在经常需要停止后重新启动的场合比较常见。

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

  》ContextStoppedEvent:当使用ConfigurableApplicationContext接口的stop()方法使ApplicationContext停止时触发该事件。此处的“停止”意味着容器管理生命周期的Bean实例将获得一个指定的停止信号,被停止的Spring容器可在此调用start()方法重新启动。

  》RequestHandledEvent:Web相关的事件,只能运用于使用DispatcherServlet的Web运用。在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件。

  Spring的这种事件模型其实就是标准的观察者设计模式。

Spring ApplicationContext的事件机制的更多相关文章

  1. 7 -- Spring的基本用法 -- 4... 使用 Spring 容器:Spring 容器BeanFactory、ApplicationContext;ApplicationContext 的国际化支持;ApplicationContext 的事件机制;让Bean获取Spring容器;Spring容器中的Bean

    7.4 使用 Spring 容器 Spring 有两个核心接口:BeanFactory 和 ApplicationContext,其中ApplicationContext 是 BeanFactory ...

  2. Tomcat与Spring中的事件机制详解

    最近在看tomcat源码,源码中出现了大量事件消息,可以说整个tomcat的启动流程都可以通过事件派发机制串起来,研究透了tomcat的各种事件消息,基本上对tomcat的启动流程也就有了一个整体的认 ...

  3. Spring 中的事件机制

    说到事件机制,可能脑海中最先浮现的就是日常使用的各种 listener,listener去监听事件源,如果被监听的事件有变化就会通知listener,从而针对变化做相应的动作.这些listener是怎 ...

  4. spring-第三篇之ApplicationContext的事件机制

    1.通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext的事件处理. 如果容器中有一个ApplicationListener ...

  5. Spring中的ApplicationContext事件机制

    ApplicationContext的事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListerner接口来实现. 1. 创建EmailEvent pu ...

  6. Spring的事件机制详解

    同步事件和异步事件 同步事件:在一个线程里,按顺序执行业务,做完一件事再去做下一件事. 异步事件:在一个线程里,做一个事的同事,可以另起一个新的线程执行另一件事,这样两件事可以同时执行. 用一个例子来 ...

  7. 观察者模式之spring事件机制

    ddsspring中的事件机制使用到设计模式中的观察者模式 ,观察者模式有两个概念,1.观察者.被观察者.2.被观察者做出相应得动作,观察者能接收到.不分析设计模式,学习下spring中的事件机制实际 ...

  8. spring的事件机制

    事件机制作为一种编程机制,在许多语言中都提供了支持.JAVA语言也不例外,java中的事件机制的参与者有3种角色: 1.event object 2.event source 3.event list ...

  9. 搞清楚Spring事件机制后:Spring的源码看起来简单多了

    本文主讲Spring的事件机制,意图说清楚: 什么是观察者模式? 自己实现事件驱动编程,对标Spring的事件机制 彻底搞懂Spring中的事件机制,从而让大家 本文内容较长,代码干货较多,建议收藏后 ...

随机推荐

  1. 360. Sort Transformed Array

    一元二次方程...仿佛回到了初中. 主要看a的情况来分情况讨论: =0,一次函数,根据b的正负单调递增递减就行了. <0,凸状..从nums[]左右两边开始往中间一边比较一边 从右往左 放: 0 ...

  2. 数据挖掘方面重要会议的最佳paper集合

    数据挖掘方面重要会议的最佳paper集合,兴许将陆续分析一下内容: 主要有KDD.SIGMOD.VLDB.ICML.SIGIR KDD (Data Mining) 2013 Simple and De ...

  3. Codeforces Round #258 (Div. 2)[ABCD]

    Codeforces Round #258 (Div. 2)[ABCD] ACM 题目地址:Codeforces Round #258 (Div. 2) A - Game With Sticks 题意 ...

  4. NYOJ128前缀式计算

    前缀式计算 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 先说明一下什么是中缀式: 如2+(3+4)*5这种我们最常见的式子就是中缀式. 而把中缀式按运算顺序加上括 ...

  5. 使用CSS、JS的几种方法

    引用CSS到html网页里的4种方法 1.行内式 在标记的style属性中设定CSS样式,这种方式本质上没有体现出CSS的优势,因此不推荐使用     <div style="widt ...

  6. codevs愚蠢的矿工(树形DP)

    /* 树形DP 根节点一定有人 然后 剩下的人没到每个孩子去 因为孩子数可能很多 不好枚举 所以转二叉树 分两部分 O(sum)就可以了 当然 转二叉树候必须顾及原来树的一些性质 如不能只选左孩子 转 ...

  7. Web api 文档以及测试工具配置

    第一步: 创建web api 在nuget 上搜索 webapitestclient (包含预发行版) 然后在 /Areas/HelpPage/Views/Help/Api.cshtml 末尾 添加 ...

  8. java编程思想-并发思维导图

  9. (转)C#文件操作

    原文连接:http://www.cnblogs.com/wangshenhe/archive/2012/05/09/2490438.html 文件与文件夹操作主要用到以下几个类: 1.File类: 提 ...

  10. 网站项目:让一般处理文件.ashx的代码有折叠功能(#region)

    注意:该方法用于网站项目.但对于其他类型的项目有一定的参考作用. 1.首先在你想被别人访问的位置新建一个ashx文件,如/System/xxx.ashx. 新建xxx.ashx的代码如下: [csha ...