【源码】Spring —— ApplicationEvent ApplicationListener ApplicationEventMulticaster

前言

本章节介绍 Spring事件 的相关类

版本

Spring 5.2.x

EventObject

public class EventObject implements java.io.Serializable {

    private static final long serialVersionUID = 5516075349620653480L;

	// 事件源
    protected transient Object source;

    public EventObject(Object source) {
        if (source == null)
            throw new IllegalArgumentException("null source");

        this.source = source;
    }

    public Object getSource() {
        return source;
    }

    public String toString() {
        return getClass().getName() + "[source=" + source + "]";
    }
}

JDK 定义的事件类,属性 source 为事件源

ApplicationEvent

public abstract class ApplicationEvent extends EventObject {

	private static final long serialVersionUID = 7099057708183571937L;

	// 事件发生的时间戳
	private final long timestamp;

	public ApplicationEvent(Object source) {
		super(source);
		this.timestamp = System.currentTimeMillis();
	}

	public final long getTimestamp() {
		return this.timestamp;
	}

}

Spring 定义的事件类,继承了 EventObject ,拓展了 timestamp 属性记录事件发生的时间

ApplicationContextEvent

public abstract class ApplicationContextEvent extends ApplicationEvent {

	public ApplicationContextEvent(ApplicationContext source) {
		super(source);
	}

	public final ApplicationContext getApplicationContext() {
		return (ApplicationContext) getSource();
	}

}

Spring容器事件 的抽象基类,相当于在 ApplicationEvent 上包装了一层,其子类即具体的 容器生命周期 事件,包括 ContextClosedEvent ContextRefreshedEvent ContextStoppedEvent ContextStartedEvent

如果是 SpringBoot 工程的话,会看到很多事件,基于监听器做了很多拓展

EventListener

public interface EventListener {
}

JDK 定义的 事件监听 标记接口

ApplicationListener

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

	// 事件处理逻辑
	void onApplicationEvent(E event);

}

Spring 定义的针对 ApplicationEvent 的监听器,是一个 函数式接口onApplicationEvent 即对目标事件的处理逻辑

SmartApplicationListener

public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {

	// 是否支持指定 事件类型(Class)
	boolean supportsEventType(Class<? extends ApplicationEvent> eventType);

	// 是否支持指定 事件源类型(Class),默认 true
	default boolean supportsSourceType(@Nullable Class<?> sourceType) {
		return true;
	}

	@Override
	// 优先级,默认最低
	default int getOrder() {
		return LOWEST_PRECEDENCE;
	}

}

SmartApplicationListener 继承了 ApplicationListener,提供对 事件类型(基于Class)事件源类型(基于Class) 的匹配

GenericApplicationListener

public interface GenericApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {

	// 是否支持指定 事件类型(Class)
	boolean supportsEventType(ResolvableType eventType);

	// 是否支持指定 事件源类型(Class),默认 true
	default boolean supportsSourceType(@Nullable Class<?> sourceType) {
		return true;
	}

	@Override
	// 优先级,默认最低
	default int getOrder() {
		return LOWEST_PRECEDENCE;
	}

}

GenericApplicationListener 继承了 ApplicationListener,提供对 事件类型(基于ResolvableType)、事件源类型(基于Class) 的匹配

关于 ResolvableType,可以阅读下面文章

关于 Type 和 ResolvableType

GenericApplicationListenerAdapter

SmartApplicationListenerGenericApplicationListener 的适配器,即通过 ClassResolvableType 的转换将两者连接起来

ApplicationEventMulticaster

public interface ApplicationEventMulticaster {

	// 监听器添加
	void addApplicationListener(ApplicationListener<?> listener);

	// 监听器 beanName 添加
	void addApplicationListenerBean(String listenerBeanName);

	// 监听器移除
	void removeApplicationListener(ApplicationListener<?> listener);

	// 监听器 beanName 移除
	void removeApplicationListenerBean(String listenerBeanName);

	// 移除所有监听器
	void removeAllListeners();

	// 事件发布
	void multicastEvent(ApplicationEvent event);

	// 指定类型的事件发布
	void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);

}

ApplicationEventMulticaster,事件组播顶层接口

  • 它是一个事件发布类,提供事件发布方法 multicastEvent
  • 同时也是一个监听器管理类,提供监听器的注册、移除相关方法

AbstractApplicationEventMulticaster

ApplicationEventMulticaster 的核心抽象类,主要实现了 监听器管理 的相关方法,它的实现也是比较经典的 Spring 式实现,不贴过多源码,此处做个概括:

  • 所有的 监听器 是由内部类 DefaultListenerRetriever 来负责管理的
  • 基于事件源、事件类型和对应的 监听器 由一个缓存集合管理,key 为内部类 ListenerCacheKey,对应监听器集合由内部类 CachedListenerRetriever 管理
  • 因此监听器的注册、移除操作委托给 DefaultListenerRetriever
  • 监听器的注册方法有 addApplicationListeneraddApplicationListenerBean,前者直接注册对应的 监听器,后者是注册一个 监听器 的 beanName,需要时直接从 容器 获取
  • 监听器的获取基于 缓存 实现
之所以说是经典的 Spring 式实现,是因为这种管理类的实现模式在 Spring 很常用且很实用

基于内部类和缓存,可以高效地管理比较复杂的内部对象

与之相似的还有 GenericConversionService 的实现

SimpleApplicationEventMulticaster

AbstractApplicationEventMulticaster 的实现类,主要实现事件发布方法

  • 主要逻辑简单清晰,根据 事件源、事件类型 基于 AbstractApplicationEventMulticaster 的实现获取对应的监听器,回调对应 监听器 方法即可
  • 它支持基于 多线程 的调用,只要初始化是传入对应 自行构造的线程池 即可,如果不传,则默认当前线程发布事件

demo

public class AEvent extends ApplicationContextEvent {
    public AEvent(ApplicationContext source) {
        super(source);
    }
}

public class BEvent extends ApplicationContextEvent {
    public BEvent(ApplicationContext source) {
        super(source);
    }
}

自定义两个事件 AEvent BEvent

public class AListener implements SmartApplicationListener {

    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {

        return AEvent.class.isAssignableFrom(eventType);
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {

        System.out.println("AListener detect a AEvent");
    }
}

public class BListener implements SmartApplicationListener {

    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {

        return BEvent.class.isAssignableFrom(eventType);
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {

        System.out.println("BListener detect a BEvent");
    }
}

针对上述事件分别定义两个监听器 AListener BListener

@Configuration
public class Config {

    @Bean
    public BListener bListener() {

        return new BListener();
    }
}

通过配置类把 BListener 注册为 beanAListener 我们打算通过 addApplicationListener 方法注册进去

@SpringBootTest
@ContextConfiguration(classes = Config.class)
public class TestMain {

    @Autowired
    BeanFactory beanFactory;

    @Autowired
    ApplicationContext applicationContext;

    @Test
    public void test() {
        SimpleApplicationEventMulticaster applicationEventMulticaster
                = new SimpleApplicationEventMulticaster(beanFactory);
        applicationEventMulticaster.addApplicationListener(new AListener());
        applicationEventMulticaster.addApplicationListenerBean("bListener");
        applicationEventMulticaster.multicastEvent(new AEvent(applicationContext));
        applicationEventMulticaster.multicastEvent(new BEvent(applicationContext));
    }
}

测试类如上:

  • 通过 addApplicationListener 方法注册 AListener
  • 通过 addApplicationListenerBean 方法把名称为 bListener 的监听器 bean 注册进去
  • 分别发布事件 AEvent BEvent,结果就是各自监听对应的事件

总结

本章节介绍了 Spring 下定义的事件相关接口 ApplicationEvent ApplicationListener ApplicationEventMulticaster,在 Spring容器 中注册的 发布事件类 其实就是 SimpleApplicationEventMulticaster

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值