zoukankan      html  css  js  c++  java
  • Spring ApplicationContext的事件机制

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

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

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

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

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

      下图简单示范了ApplicationContext事件

      

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

     1 import org.springframework.context.ApplicationEvent;
     2 
     3 public class EmailEvent extends ApplicationEvent{
     4 
     5     private static final long serialVersionUID = -7056841418193254583L;
     6 
     7     private String address;
     8     private String text;
     9     public EmailEvent(Object source) {
    10         super(source);
    11     }
    12     public String getAddress() {
    13         return address;
    14     }
    15     public void setAddress(String address) {
    16         this.address = address;
    17     }
    18     public String getText() {
    19         return text;
    20     }
    21     public void setText(String text) {
    22         this.text = text;
    23     }
    24     
    25 }

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

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

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

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

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

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

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

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

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

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

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

    1 容器本身事件: 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]
    2 需要发送的邮件的接收地址:123456@163.com
    3 需要发送邮件的邮件正文: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的这种事件模型其实就是标准的观察者设计模式。

  • 相关阅读:
    iOS判断为空或者只为空格
    一个CRM OData的性能问题分析
    什么是SAP UI5的Component-preload.js
    SAP CRM的状态管理和权限控制的集成
    如何使用SAP Intelligent Robotic Process Automation自动操作Excel
    利用S_MEMORY_INSPECTOR分析内存泄漏问题
    SAP CRM WebClient UI的搜索条件是怎么渲染出来的
    SAP CRM WebClient UI的内存清理策略分析
    SAP CRM产品主数据应用里value node和model node的转换
    如何查找SAP Fiori UI上某个字段对应的底层数据库表
  • 原文地址:https://www.cnblogs.com/ArtsCrafts/p/Spring_Event.html
Copyright © 2011-2022 走看看