16.容器事件

16.容器事件

1. 概念

Spring的ApplicationContext能够发布事件并且允许注册相应的事件监听器,因此,它拥有一套完善的时间发布和监听机制。,5个基本概念:

事件体系

  1. 事件(EventObject):发送的事件

  2. 事件监听器:监听事件,事件发生时,做出相应的处理

  3. 事件源:事件的产生者,任何一个EventObject必须拥有一个事件源

  4. 事件监听器注册表:组件或者框架的事件监听器不可能漂浮在空中,而必须有所存在,当事件产生时,会通知这些位于事件监听器注册表中的监听器

  5. 事件广播器:事件和事件监听器沟通的桥梁,负责把事件通知给事件监听器

    事件体系,其实是观察者的一种具体实现方式,观察者模式,请参见

2. Spring事件类结构

1. 事件类 ApplicationEvent

2. 事件监听接口 ApplicationListener

3. 事件广播 ApplicationEventMulticaster

​ 当事件发容器事件时,容器主控程序将调用时间广播器将事件通知给事件监听器注册表中的事件监听器.

3. 实现示例

通过模拟发送邮件的例子模拟事件的发布

  1. 事件:MailSendEvent

    package com.desmond.springlearning.event;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.event.ApplicationContextEvent;
    import org.springframework.stereotype.Component;
    
    /**
     * @author presleyli
     * @date 2018/10/28 下午1:25
     */
    public class MailSenderEvent extends ApplicationContextEvent {
        private String to;
        public MailSenderEvent(ApplicationContext source, String to) {
            super(source);
            this.to = to;
        }
    
        public String getTo() {
            return to;
        }
    
        public void setTo(String to) {
            this.to = to;
        }
    }
    
    
  2. 事件监听器,当收到事件通知,负责具体业务逻辑处理

    package com.desmond.springlearning.event;
    
    import org.springframework.context.ApplicationListener;
    import org.springframework.stereotype.Component;
    
    /**
     * @author presleyli
     * @date 2018/10/28 下午1:26
     */
    @Component
    public class MailSenderListener implements ApplicationListener<MailSenderEvent> {
        public void onApplicationEvent(MailSenderEvent mailSenderEvent) {
            System.out.println("listener向" + mailSenderEvent.getTo() + "发送了一封邮件.");
        }
    }
    
    
  3. 事件源

    package com.desmond.springlearning.event;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author presleyli
     * @date 2018/10/28 下午1:28
     */
    @ComponentScan(basePackages = "com.desmond.springlearning.event")
    @Configuration
    public class MailSender {
        @Autowired
        private ApplicationContext applicationContext;
    
        public void sendMail(String to) {
            System.out.println("MailSender模拟发邮件...");
    
            applicationContext.publishEvent(new MailSenderEvent(this.applicationContext, to));
        }
    }
    
    
  4. 测试类:

    package com.desmond.springlearning.event;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * @author presleyli
     * @date 2018/10/28 下午1:31
     */
    public class Test {
        public static void main(String[] args) {
            ApplicationContext applicationContext =
                    new AnnotationConfigApplicationContext(MailSender.class);
    
            MailSender mailSender = applicationContext.getBean(MailSender.class);
            mailSender.sendMail("desmond@desmond.com");
        }
    }
    
    
  5. Output

    MailSender模拟发邮件...
    listener向desmond@desmond.com发送了一封邮件.
    
  6. 过程分析:

    1. 事件(EventObject):MailSendEvent

    2. 事件监听器:MailSenderListener

    3. 事件源:MailSender

    4. 事件监听器注册表:ApplicationEventMulticaster, Application根据反射机制,从BeanDefinitionRegistry中找出所有实现了ApplicationListener的Bean,并将他们注册至ApplicationEventMulticaster. 其注册与广播方法为:

      /*
       * Copyright 2002-2015 the original author or authors.
       *
       * Licensed under the Apache License, Version 2.0 (the "License");
       * you may not use this file except in compliance with the License.
       * You may obtain a copy of the License at
       *
       *      http://www.apache.org/licenses/LICENSE-2.0
       *
       * Unless required by applicable law or agreed to in writing, software
       * distributed under the License is distributed on an "AS IS" BASIS,
       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       * See the License for the specific language governing permissions and
       * limitations under the License.
       */
      
      package org.springframework.context.event;
      
      import org.springframework.context.ApplicationEvent;
      import org.springframework.context.ApplicationListener;
      import org.springframework.core.ResolvableType;
      
      /**
       * Interface to be implemented by objects that can manage a number of
       * {@link ApplicationListener} objects, and publish events to them.
       *
       * <p>An {@link org.springframework.context.ApplicationEventPublisher}, typically
       * a Spring {@link org.springframework.context.ApplicationContext}, can use an
       * ApplicationEventMulticaster as a delegate for actually publishing events.
       *
       * @author Rod Johnson
       * @author Juergen Hoeller
       * @author Stephane Nicoll
       */
      public interface ApplicationEventMulticaster {
      
      	/**
      	 * Add a listener to be notified of all events.
      	 * @param listener the listener to add
      	 */
      	void addApplicationListener(ApplicationListener<?> listener);
      
      	/**
      	 * Add a listener bean to be notified of all events.
      	 * @param listenerBeanName the name of the listener bean to add
      	 */
      	void addApplicationListenerBean(String listenerBeanName);
      
      	/**
      	 * Remove a listener from the notification list.
      	 * @param listener the listener to remove
      	 */
      	void removeApplicationListener(ApplicationListener<?> listener);
      
      	/**
      	 * Remove a listener bean from the notification list.
      	 * @param listenerBeanName the name of the listener bean to add
      	 */
      	void removeApplicationListenerBean(String listenerBeanName);
      
      	/**
      	 * Remove all listeners registered with this multicaster.
      	 * <p>After a remove call, the multicaster will perform no action
      	 * on event notification until new listeners are being registered.
      	 */
      	void removeAllListeners();
      
      	/**
      	 * Multicast the given application event to appropriate listeners.
      	 * <p>Consider using {@link #multicastEvent(ApplicationEvent, ResolvableType)}
      	 * if possible as it provides a better support for generics-based events.
      	 * @param event the event to multicast
      	 */
      	void multicastEvent(ApplicationEvent event);
      
      	/**
      	 * Multicast the given application event to appropriate listeners.
      	 * <p>If the {@code eventType} is {@code null}, a default type is built
      	 * based on the {@code event} instance.
      	 * @param event the event to multicast
      	 * @param eventType the type of event (can be null)
      	 */
      	void multicastEvent(ApplicationEvent event, ResolvableType eventType);
      
      }
      
    5. 事件广播器:ApplicationEventMulticaster.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值