五个人在报社订阅了报纸。报社一旦有了新报纸,就派员工分别送到这五个人手里。在这个例子中,“报纸”就是事件,“报社”就是广播器,五个订阅者就是监听器。广播器收到事件,把事件传给监听器,监听器对事件做一些事情。这样的例子属于观察者模式。

  1. 观察者模式:A类负责接收新信息,B、C、D类一直关注着A。A类一旦有了新信息,就发送给B、C、D类,B、C、D类收到信息作出不同的操作。这就是观察者模式。具体到代码中,A中设置一个变量message(这就是信息),当message改变时,调用B、C、D的performMessage(message)方法(这就把message发送给B、C、D类并让B、C、D类开始处理了。)在这里,B、C、D类是倾听者(相当于监听器),而A是发布者(相当于广播器),message就是事件。
  2. java的观察者模式:java.util.Observer属于倾听者接口,编写自己的倾听者只需要实现此接口。java.util.Observable是发布者,编写自己的发布者需要扩展此类。
  3. 事件体系:有下面几个要素:
    1. 事件:像新报纸一样,发生了事情,这个事情就是事件。
    2. 事件源:事情的发起者。
    3. 事件广播器:把事件通知给事件监听器。(类似报社)。
    4. 事件监听器:接收事件并针对事件做一些工作。(订阅者分别读了报纸后有不同的反应)。
    5. 事件监听器注册表:框架的事件监听器都存放在注册表里。
  4. 事件体系角色图,事件源产生事件,把事件传给事件广播器,事件广播器再把事件传给事件监听器注册表中的事件监听器。
  5. Spring是如何使用事件广播器发布事件的
    1. 要发布事件,必须有几个要素:事件类、广播器、监听器。
    2. java.util.EventObject是java的事件类,spring的ApplicationContextEvent扩展了EventObject类。继承关系是:,其中,ApplicationEvent继承了EventObject。我们写自己的spring事件类,可以扩展ApplicationEvent。
    3. java.util.EventListener是java的事件监听器类,spring的ApplicationListener扩展了EventListener接口。可以扩展ApplicationListener来编写自己的监听器(写好后在配置文件中配置)。
    4. spring的事件广播器继承关系:事件监听器注册表由事件广播器提供。可以实现ApplicationEventMulticaster写自己的广播器,如果没有自己的广播器,spring将使用默认的SimpleApplicationEventMulticaster广播器。
    5. 事件类、监听器类、广播器类都具备了,再写一个事件源类(制造事件,必须实现ApplicationContextAware接口,覆盖setApplicationContext方法,从而获取ApplicationContext实例。写好后在配置文件中配置),让整个事件过程运作起来。具体运作过程:

      1. spring容器启动时会初始化事件广播器,同时事件广播器提供了监听器注册表。
      2. spring根据配置文件获取所有监听器并放到监听器注册表中。
      3. spring容器启动完成后运行事件源类,制造事件,并把事件传给广播器,广播器再把事件传给监听器。
  6. 一个实例
    1. 编写事件类:

      public class MailSendEvent extends ApplicationContextEvent {
      private String to; public MailSendEvent(ApplicationContext source, String to) {
      super(source);
      this.to = to;
      }
      public String getTo() { return this.to;
      }
      }
    2. 编写事件监听器类:
      public class MailSendListener implements ApplicationListener<MailSendEvent>{
      
          public void onApplicationEvent(MailSendEvent event) {
      MailSendEvent mse = (MailSendEvent) event;
      System.out.println("MailSendListener:向" + mse.getTo() + "发送完一封邮件");
      }
      }
    3. 编写事件源类(spring容器启动后加载该类驱动整个事件传送过程)(下面代码中,在publishEvent(mse)内部,spring委托ApplicationEventMulticaster广播器将事件通知给监听器):
      public class MailSender implements ApplicationContextAware {
      
          private ApplicationContext ctx ;
      
          public void setApplicationContext(ApplicationContext ctx)
      throws BeansException {
      this.ctx = ctx; }
      public void sendMail(String to){
      System.out.println("MailSender:模拟发送邮件...");
      MailSendEvent mse = new MailSendEvent(this.ctx,to);
      ctx.publishEvent(mse);
      }
      }
    4. 在XML中配置监听器和事件源类:
        <bean class="com.baobaotao.event.MailSendListener"/>
      <bean id="mailSender" class="com.baobaotao.event.MailSender"/>
    5. 主函数中调用事件源:
      public static void main(String[] args) {
      String resourceFile = "com/baobaotao/event/beans.xml";
      ApplicationContext ctx = new ClassPathXmlApplicationContext(resourceFile);
      MailSender mailSender = ctx.getBean(MailSender.class);
      mailSender.sendMail("test mail.");
      System.out.println("done.");
      }

(spring-第15回【IoC基础篇】)容器事件的更多相关文章

  1. Spring+SpringMVC+MyBatis+easyUI整合基础篇(六)maven整合SSM

    写在前面的话   承接前文<Spring+SpringMVC+MyBatis+easyUI整合基础篇(五)讲一下maven>,本篇所讲述的是如何使用maven与原ssm项目整合,使得一个普 ...

  2. Spring+SpringMVC+MyBatis+easyUI整合基础篇(八)mysql中文查询bug修复

    写在前面的话 在测试搜索时出现的问题,mysql通过中文查询条件搜索不出数据,但是英文和数字可以搜索到记录,中文无返回记录.本文就是写一下发现问题的过程及解决方法.此bug在第一个项目中点这里还存在, ...

  3. Spring+SpringMVC+MyBatis+easyUI整合基础篇(十一)SVN服务器进阶

    日常啰嗦 上一篇文章<Spring+SpringMVC+MyBatis+easyUI整合基础篇(十)SVN搭建>简单的讲了一下SVN服务器的搭建,并没有详细的介绍配置文件及一些复杂的功能, ...

  4. Spring+SpringMVC+MyBatis+easyUI整合基础篇(十二)阶段总结

    不知不觉,已经到了基础篇的收尾阶段了,看着前面的十几篇文章,真的有点不敢相信,自己竟然真的坚持了下来,虽然过程中也有过懒散和焦虑,不过结果还是自己所希望的,克服了很多的问题,将自己的作品展现出来,也发 ...

  5. Spring+SpringMVC+MyBatis+easyUI整合基础篇

    基础篇 Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简介 Spring+SpringMVC+MyBatis+easyUI整合基础篇(二)牛刀小试 Spring+S ...

  6. (spring-第2回【IoC基础篇】)Spring的Schema,基于XML的配置

    要深入了解Spring机制,首先需要知道Spring是怎样在IoC容器中装配Bean的.而了解这一点的前提是,要搞清楚Spring基于Schema的Xml配置方案. 在深入了解之前,必须要先明白几个标 ...

  7. Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简介

    很久之前就打算开始写一下自己的技术博客了,实在抽不出时间所以计划一直搁置了,最近项目进度渐渐缓了下来,不那么忙了,也因此开始筹备自己的博客.说到这次博客的主角,也是无心插柳找到的,来源于两年前自己写的 ...

  8. Spring+SpringMVC+MyBatis+easyUI整合基础篇(九)版本控制

    日常啰嗦 还好在第一篇文章里就列好了接下来的主线及要写的知识点,不然都不知道要写什么东西了,开篇里已经列了基础篇要讲svn和git的知识点,所以这一篇就写一下版本控制. 项目实际效果展示在这里,账密: ...

  9. 【SSM之旅】Spring+SpringMVC+MyBatis+Bootstrap整合基础篇(一)项目简介及技术选型相关介绍

    试水 一直想去搭建个自己的个人博客,苦于自己的技术有限,然后也个人也比较懒散.想动而不能动,想动而懒得动,就这么一直拖到了现在.总觉得应该把这几年来的所学总结一番,这样才能有所成长. 不知在何时,那就 ...

  10. Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简述及技术选型介绍

    作者:13GitHub:https://github.com/ZHENFENG13版权声明:本文为原创文章,未经允许不得转载. 萌芽阶段 很久之前就开始打算整理一下自己的技术博客了,由于各种原因(借口 ...

随机推荐

  1. [saiku] 登陆/选择cube 时发生了什么

    一 登陆saiku时发生了什么 大致流程 saiku 默认有admin和两个开发人员的身份 登陆saiku时,后台用户认证成功后创建了用户信息session 并在session中存储了随机生成的一个s ...

  2. SQL Server数据库(SQL Sever语言 CRUD)

    使用SQL Sever语言进行数据库的操作 常用关键字identity 自增长primary key 主键unique 唯一键not null 非空references 外键(引用) 在使用查询操作数 ...

  3. js便签笔记(13)——jsonp其实很简单【ajax跨域请求】

    前两天被问到ajax跨域如何解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了许多资料,原来如此... 为何一直知道jsonp,但一直迷迷糊糊的不明白 ...

  4. Servlet视频学习笔记 57-58 (servlet入门和调用过程)

    网易云课堂<30天轻松掌握JavaWeb视频>servlet部分 课时57 servlet开发入门 servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术.S ...

  5. 源代码解读Cas实现单点登出(single sign out)功能实现原理

    关于Cas实现单点登入(single sing on)功能的文章在网上介绍的比较多,想必大家多多少少都已经有所了解,在此就不再做具体介绍.如果不清楚的,那只能等我把single sign on这块整理 ...

  6. Octopus系列之HttpCustom2.0模板引擎的处理,一个bug的分析

    实现的目标是: 1.实现手机和PC模板请求的区分:使得来自两种不同设备请求的时候,各自路由到不同的目录中去 2.保持只有一个引擎实例对象 最后发现一个bug就是,当我从PC访问时初始化了PC的目录,呈 ...

  7. AjaxUpload.3.5.js之ASP.NET 文件上传

    一.引入js文件 <script type="text/javascript" src="/Scripts/JQuery.min.js"></ ...

  8. qt--- vs

    qt with vs 1.安装vs2012: 2.下载Qt 5.2.0 for Windows 32-bit (VS 2012, 579 MB) 和 Visual Studio Add-in 1.2. ...

  9. S1:运算符

    中括号和小括号的用法: 一般而言,对象中的属性的值是通过点(.)运算符来取值,但是考虑到这样一种情况,我们在遍历一个对象的时候,对其中的属性的键(key)是一无所知的,我们怎么通过点(.)来访问呢?这 ...

  10. 转: CSS中float和clear的理解

    float:浮动,比如,默认的,我们知道,div是占满一行的,现在我们想把两个div显示在一行上,那怎么办呢<div style="width:100px;">1111 ...