zoukankan      html  css  js  c++  java
  • spring 自定义事件发布及监听(简单实例)

    前言:

    Spring的AppilcaitionContext能够发布事件和注册相对应的事件监听器,因此,它有一套完整的事件发布和监听机制。

    流程分析:

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

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

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

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

    通过流程图,可以看出它们是如何各司其职的,如下:

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

    结构分析:

    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"/>

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

  • 相关阅读:
    Python3之random模块常用方法
    Go语言学习笔记(九)之数组
    Go语言学习笔记之简单的几个排序
    Go语言学习笔记(八)
    Python3之logging模块
    Go语言学习笔记(六)
    123. Best Time to Buy and Sell Stock III(js)
    122. Best Time to Buy and Sell Stock II(js)
    121. Best Time to Buy and Sell Stock(js)
    120. Triangle(js)
  • 原文地址:https://www.cnblogs.com/xinde123/p/8918714.html
Copyright © 2011-2022 走看看