深入理解Spring的容器内事件发布监听机制(3)

//邮件服务监听器
        MailTaskFinishListener mailListener = new MailTaskFinishListener("takumiCX@163.com");

//事件发布器
        TaskFinishEventPublisher publisher = new TaskFinishEventPublisher();

//注册邮件服务监听器
        publisher.register(mailListener);

//发布事件
        publisher.publishEvent(event);

}
}

测试结果

深入理解Spring的容器内事件发布监听机制

如果后期因为需求变动需要在任务结束时将结果以短信的方式发送给用户,则可以再添加一个短信服务监听器

/**
 * @author: takumiCX
 * @create: 2018-11-03
 **/
@Data
@AllArgsConstructor
public class SmsTaskFinishListener implements TaskFinishEventListner {

private String address;

@Override
    public void onTaskFinish(TaskFinishEvent event) {
        System.out.println("Send Message to "+address+" Task:"+event.getSource());
    }
}

在测试代码中添加如下代码向事件发布器注册该监听器

SmsTaskFinishListener smsListener = new SmsTaskFinishListener("123456789");

//注册短信服务监听器
publisher.register(smsListener);

最后运行结果如下

深入理解Spring的容器内事件发布监听机制

基于JDK的支持要实现对自定义事件的监听还是比较麻烦的,要做的工作比较多。而且自定义的事件发布器也不能提供对所有事件的统一发布支持。基于Spring框架实现自定义事件监听则要简单很多,功能也更加强大。

3.Spring容器对事件监听机制的支持

Spring容器,具体而言是ApplicationContext接口定义的容器提供了一套相对完善的事件发布和监听框架,其遵循了JDK中的事件监听标准,并使用容器来管理相关组件,使得用户不用关心事件发布和监听的具体细节,降低了开发难度也简化了开发流程。下面看看对于事件监听机制中的各主要角色,Spring框架中是如何定义的,以及相关的类体系结构

事件
Spring为容器内事件定义了一个抽象类ApplicationEvent,该类继承了JDK中的事件基类EventObject。因而自定义容器内事件除了需要继承ApplicationEvent之外,还要传入事件源作为构造参数。

深入理解Spring的容器内事件发布监听机制

事件监听器
Spring定义了一个ApplicationListener接口作为为事件监听器的抽象,接口定义如下

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

/**
    * Handle an application event.
    * @param event the event to respond to
    */
  void onApplicationEvent(E event);

}

1.该接口继承了JDK中表示事件监听器的标记接口EventListener,内部只定义了一个抽象方法onApplicationEvent(evnt),当监听的事件在容器中被发布,该方法将被调用。
2.同时,该接口是一个泛型接口,其实现类可以通过传入泛型参数指定该事件监听器要对哪些事件进行监听。这样有什么好处?这样所有的事件监听器就可以由一个事件发布器进行管理,并对所有事件进行统一发布,而具体的事件和事件监听器之间的映射关系,则可以通过反射读取泛型参数类型的方式进行匹配,稍后我们会对原理进行讲解。
3.最后,所有的事件监听器都必须向容器注册,容器能够对其进行识别并委托容器内真正的事件发布器进行管理。

事件发布器
ApplicationContext接口继承了ApplicationEventPublisher接口,从而提供了对外发布事件的能力,如下所示

深入理解Spring的容器内事件发布监听机制

那么是否可以说ApplicationContext,即容器本身就担当了事件发布器的角色呢?其实这是不准确的,容器本身仅仅是对外提供了事件发布的接口,真正的工作其实是委托给了具体容器内部一个ApplicationEventMulticaster对象,其定义在AbstractApplicationContext抽象类内部,如下所示

/** Helper class used in event publishing */
private ApplicationEventMulticaster applicationEventMulticaster;

所以,真正的事件发布器是ApplicationEventMulticaster,这是一个接口,定义了事件发布器需要具备的基本功能:管理事件监听器以及发布事件。其默认实现类是
SimpleApplicationEventMulticaster,该组件会在容器启动时被自动创建,并以单例的形式存在,管理了所有的事件监听器,并提供针对所有容器内事件的发布功能。

3.1 基于Spring实现对任务执行结果的监听

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8aa7eccef7a6ee573b4af64ab1388374.html