Spring事件监听机制源码解析

本文详细介绍了Spring的事件监听机制,从事件监听的基本概念、JDK的事件监听机制入手,深入探讨了Spring如何注册和发布事件,重点分析了`ApplicationEventMulticaster`的作用和工作流程,包括监听器的注册、事件的发布,以及Spring如何根据事件找到对应的监听器。通过对源码的解析,帮助读者理解Spring事件监听机制的内部实现。
摘要由CSDN通过智能技术生成

1 什么是事件监听机制

前一篇文章简述了观察者模式,事件监听机制是对观察者模式的另一种实现,本质上均是多个对象(观察者/监听器)依赖于一个对象(被观察者/事件)的状态的关系。
观察者模式中主要有角色:观察者(Observer)、被观察者(Subject,Obserable).
事件监听机制中的主要角色:事件(Event),事件源(Source),事件发布器(EventPublisher),监听器(Listener)


两者主要区别是什么?
观察者模式中:被观察者(Subject)需要主动维护观察者的引用集合,并通知观察者状态变化
事件监听机制中:事件发布器承担了维护观察者的引用集合,并通知观察者状态变化的功能。

观察者模式 事件监听机制
观察者(Observer) 监听器(Listener)
被观察者(Subject,Obserable) 事件(Event),事件源(Source)
被观察者(Subject,Obserable)中负责维护主题与观察者映射关系以及在自身状态改变时通知观察者的职责 事件发布器(EventPublisher)

事件源(Source):产生事件的源头,也即发生事件的组件。例如按钮(事件源)和点击(事件)的关系
事件(Event):对一个组件的某种同类型操作动作的集合.
监听器(Listener):首先,监听组件,观察组件有没有发生某类事件;其次如果监听的组件发生了某类事件,则调用对应的动作处理方法立刻处理这个事件。
这些角色/组件之间的关系如图所示(网图侵删):
在这里插入图片描述
事件发布器(EventPublisher)组件在图中主要表现为:将监听器注册到事件源上,在必要的时候调用事件所对应的监听器处理事件。

2 JDK的事件监听机制

jdk中为实现事件监听机制提供了两个基础类:EventObject和EventListener,均是java.util包的类。

2.1 EventObject(事件)

EventObject:表示事件基类,该EventObject定义了事件对象,其中source表示事件源(或者任意其它对象),自定义事件扩展该类,源码如下:

package java.util;
/**
 * <p>
 * The root class from which all event state objects shall be derived.
 * <p>
 * All Events are constructed with a reference to the object, the "source",
 * that is logically deemed to be the object upon which the Event in question
 * initially occurred upon.
 *
 * @since JDK1.1
 */

public class EventObject implements java.io.Serializable {
   

    private static final long serialVersionUID = 5516075349620653480L;

    /**
     * 表示事件最初发生的地方(事件源)
     * The object on which the Event initially occurred.
     */
    protected transient Object  source;

    /**
     * Constructs a prototypical Event.
     *
     * @param    source    The object on which the Event initially occurred.
     * @exception  IllegalArgumentException  if source is null.
     */
    public EventObject(Object source) {
   
        if (source == null)
            throw new IllegalArgumentException("null source");

        this.source = source;
    }

    /**
     * The object on which the Event initially occurred.
     *
     * @return   The object on which the Event initially occurred.
     */
    public Object getSource() {
   
        return source;
    }

    /**
     * Returns a String representation of this EventObject.
     *
     * @return  A a String representation of this EventObject.
     */
    public String toString() {
   
        return getClass().getName() + "[source=" + source + "]";
    }
}

2.2 EventListener(事件监听器)

EventListener:事件监听器,是一个标记接口,自定义监听器扩展该监听器,源码如下:

package java.util;

/**
 * A tagging interface that all event listener interfaces must extend.
 * @since JDK1.1
 */
public interface EventListener {
   
}

2.3 EventPublisher(事件发布器)

该类jdk没有提供相应的实现,需要我们自己手动编写。

2.4 基于jdk的事件机制示例

该示例以过红绿灯为例(类似前文的观察者模式)

2.4.1 事件源(红绿灯)

//事件源
public class Source {
   
    public String color = "red";
}

2.4.1 事件

public class SwitchLightEvent extends EventObject {
   

    public SwitchLightEvent(Object source) {
   
        super(source);
    }
}

2.4.2 事件监听器

自定义事件监听器接口

public interface ObjectListener extends EventListener {
   
    public void deal(SwitchLightEvent event);
}

自定义监听器实例

public class CarListener implements ObjectListener{
   

    /**
     * 监听器接收到事件对象也可以通过getSource获得事件源对象
     * 这样可以根据事件及事件源来执行相应的处理逻辑
     * @param event 事件对象
     */
    public void deal(SwitchLightEvent event) {
   
        System.out.println(event.getSource()+"  Car Run");
    }
}
public class ManListener implements ObjectListener {
   

    public void deal(SwitchLightEvent event) {
   
        System.out.println(event.getSource()+"  Man Run");
    }
}

2.4.3 事件发布器

public class SwitchLightEventPublisher {
   
    //观察者对象引用的集合
    private List<ObjectListener> listeners = new ArrayList<ObjectListener>();

    //注册监听器
    public void attach(ObjectListener listener) {
   
        if (listener == null) {
   
            return;
        }
        listeners.add(listener);
    }

    //删除监视器
    public void detach(ObjectListener listener) {
   
        Iterator<ObjectListener> iterator = listeners.iterator();
        while (iterator.hasNext()) {
   
            ObjectListener next = iterator.next();
            if (listener.equals(next)) {
   
                iterator.remove();
            }
        }
    }

    //发布红绿灯切换事件
    public void publishEvent(SwitchLightEvent event) {
   
        for (ObjectListener observer : listeners) {
   
      
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值