汉莫拉比

(spring-第15回【IoC基础篇】)容器事件

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

  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.");
          }

       

posted on 2016-01-24 02:09  搬砖的小学生  阅读(1051)  评论(0编辑  收藏  举报