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

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

  • 相关阅读:
    EXCEL文本转数值方法我找的好苦啊(转) Kevin
    C# 自定义控件和自定义事件 Kevin
    MVC3 示例项目中 Authentication 验证密码错误。 Kevin
    如何选定文件或文件夹
    软件工程师的必修课:PKM
    “个人知识管理”的定义和包含的内容
    如何评价一个专业性的工具软件
    教你从“搜索”的角度来选取个人知识管理软件
    国内领先的PKM(个人知识库管理)工具
    如果界面还不行就跳闽江
  • 原文地址:https://www.cnblogs.com/xinde123/p/8918714.html
Copyright © 2011-2022 走看看