spring 自定义事件发布及监听(简单实例)

前言:web

Spring的AppilcaitionContext可以发布事件和注册相对应的事件监听器,所以,它有一套完整的事件发布和监听机制。spring

流程分析:app

在一个完整的事件体系中,除了事件监听器之外,还应该有3个概念;框架

1. 事件源:事件的产生者,任何一个event都必须有一个事件源;ide

2. 事件广播器:它是事件和事件监听器之间的桥梁,负责把事件通知给事件监听器;函数

3. 事件监听器注册表:就是spring框架为全部的监听器提供了一个存放的地方;测试

经过流程图,能够看出它们是如何各司其职的,以下:this

其实经过流程图,咱们很容易发现事件体系就是观察者模式的具体实现,它并无任何的神秘之处。spa

结构分析:code

1.  事件类ApplicaitonEvent):目前spring框架自己仅仅提供了几个事件,不少的事件都是须要自定义的。

 ApplicationEvent惟一的构造函数是ApplicaitonEvent(Object source),经过source指定事件源。  它有两个子类;

(1)ApplicationContextEvent:容器事件,也就是说事件源是ApplicationContext,框架提供了四个子类,分别表明容器启动,刷新,中止和关闭事件。

(2)RequestHandleEvent:这是一个与Web应用相关的事件,当一个请求被处理后,才会产生该事件。

通常来讲,咱们都是扩展ApplicationEvent来自定义事件。下面会有栗子。

 

2. 事件监听器接口ApplicationListener

全部的监听器都须要实现该接口,该接口只定义了一个方法:onApplicaitonEvent (E event),该方法接收事件对象,在该方法中编写事件的响应处理逻辑。

 

实例分析:

经过一个实例来说解事件发布和事件监听的过程。这个例子包括一个模拟的邮件发送器MailSender,它在向目的地发送邮件的时候 会产生一个MailSendEvent事件,咱们同时向容器中注册了该事件的监听器MailSendListener;

上代码:MailSendEvent

/**
 * 继承了ApplicationContextEvent,就是个容器事件
 */
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;
    }
}

 

很明显,这里的source是ApplicationContext容器。

咱们再定义一个该事件的监听器MailSendListener,以下

@Component
public class MailSendListener implements ApplicationListener<MailSendEvent>{
    @Override
    public void onApplicationEvent(MailSendEvent mailSendEvent) {
        MailSendEvent event = mailSendEvent;
        System.out.println("MailSender向"+ event.getTo()+ "发送了邮件");
    }
}

 

上述说起到全部的监听器都必需要实现ApplicationListener,这里是个泛型类,指定了该监听器只监听MailSendEvent事件。

OK,那咱们如今来触发事件:MailSender,也就是事件源

@Component("mailSender")
public class MailSender {
    @Autowired
    private ApplicationContext applicationContext;  //容器事件由容器触发

    public void sendMail(String to){
        System.out.println("MailSender开始发送邮件");
        MailSendEvent event = new MailSendEvent(applicationContext,to);
        applicationContext.publishEvent(event);
    }
}

 

最后写个测试类,容器启动:

public class SpringEventTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("web/WEB-INF/applicationContext.xml");
        MailSender sender  = (MailSender)context.getBean("mailSender");
        sender.sendMail("北京");
    }
}

 

记得在applicationContext.xml里面加上注解扫描啊,我这里都是放在springEvent包里的,因此加上  <context:component-scan base-package="springEvent"/>

好了,启动容器,发送邮件:执行结果以下

相关文章
相关标签/搜索