其他分享
首页 > 其他分享> > Spring 事件驱动,自定义事件监听

Spring 事件驱动,自定义事件监听

作者:互联网

目录


 

概述

spring引入了事件机制,支持 ApplicationEvent(应用事件),可以对指定事件进行监听处理。
 

事件驱动的3要素

spring的事件驱动模型

观察者模式的典型应用,监听器订阅指定类型的事件,事件发布器发布事件时,会自动通知订阅了该事件类型的所有监听器。

 

源码分析

ApplicationEvent 应用事件

public abstract class ApplicationEvent extends EventObject {

	private static final long serialVersionUID = 7099057708183571937L;

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

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

	public ApplicationEvent(Object source, Clock clock) {
		super(source);
		this.timestamp = clock.millis();
	}

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

}

jdk自带的对象事件 EventObject 定义了一个Object类型的成员变量表示事件源,ApplicationEvent 在 EventObject 的基础上增加了一个long型的成员变量表示事件的发生时间。

 

spring中常见的事件类型

ApplicationEvent 表示spring的应用事件,是spring事件的公共父类,这个类有很多子类,表示具体的事件类型。
 

spring常见的事件类型(5种标准事件)

方法名称触发时机对应的触发方法
ContextRefreshedEvent
上下文更新事件
Event raised when an ApplicationContext gets initialized or refreshed
容器被初始化或被更新时触发
调用 ConfigurableApplicationContex t的 refresh() 方法
ContextStartedEvent
上下文开始事件
Event raised when an ApplicationContext gets started
容器启动时触发
调用 ConfigurableApplicationContext 的 start() 方法
ContextStoppedEvent
上下文停止事件
Event raised when an ApplicationContext gets stopped
容器被停止时触发
调用 ConfigurableApplicationContext 的 stop() 方法
ContextClosedEvent
上下文关闭事件
Event raised when an ApplicationContext gets closed
容器被关闭时触发
调用 ConfigurableApplicationContext 的 close() 方法
RequestHandledEvent
请求(已)处理事件
Event raised when a request is handled within an ApplicationContext
请求被处理时触发
说明:如果是 springmvc,会直接使用 RequestHandledEvent 的子类 ServletRequestHandledEvent

start()、stop() 都是 ConfigurableApplicationContext 接口从 Lifecycle 接口继承的,以上4个方法 ConfigurableApplicationContext 都未提供实现。

spring支持自定义的应用事件,可以继承 ApplicationEvent 实现自定义的应用事件。

 

ApplicationListener 事件监听器

//继承了jdk自带的事件监听器 EventListener,泛型指定要监听的事件类型
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

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

	static <T> ApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer) {
		return event -> consumer.accept(event.getPayload());
	}

}

 

ApplicationEventPublisher 事件发布器

@FunctionalInterface
public interface ApplicationEventPublisher {

	//发布事件,默认实现是调用下面的方法
	default void publishEvent(ApplicationEvent event) {
		publishEvent((Object) event);
	}

	//发布事件,参数是要发布的事件
	void publishEvent(Object event);

}
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
	//...
}

事件发布器只被 ApplicationContext 系列接口继承实现了,可以调用ApplicationContext 实例发布事件。

 

实际使用

自定义事件

/**
 * 自定义事件,需要继承 ApplicationEvent
 */
public class MyApplicationEvent extends ApplicationEvent {

    /**
     * 在构造方法中调用父类对应的构造方法
     *
     * @param source 事件源
     */
    public MyApplicationEvent(Object source) {
        super(source);
    }

}

 

编写事件监听器

事件监听器有2种写法
 
1、ApplicationListener 接口方式

/**
 * 自定义的事件监听器,需要实现 ApplicationListener
 * 泛型指定要监听的事件类型,ApplicationEvent 则表示监听所有的spring应用事件
 */
@Component  //放到容器中
public class MyApplicationEventListener implements ApplicationListener<MyApplicationEvent> {

    /**
     * 处理事件。可通过event获取事件源、发生时间
     * 如果处理很耗时,可以使用标注 @Async 异步执行
     *
     * @param event
     */
    @Override
    public void onApplicationEvent(MyApplicationEvent event) {
        System.out.println("接收到事件:" + event);
    }

}

一个类对应一个监听器,往往需要编写多个自定义的监听器类
 

2、注解方式

@Component  //放到容器中
public class MyApplicationEventListener {

    /**
     * 使用 @EventListener 标识为监听器,形参类型即要监听的事件类型
     * 如果处理很耗时,可以使用标注 @Async 异步执行
     *
     * @param event 事件
     */
    @EventListener
    public void MyApplicationEvent(MyApplicationEvent event) {
        System.out.println("接收到事件:" + event);
    }

}

一个方法对应一个监听器,可在一个类中写多个监听器
 

说明

如果监听器中处理事件的方法执行很耗时,可以使用springboot自带的异步方法@Async,让方法异步执行,不阻塞主线程。

异步方法需要在引导类上加 @EnableAsync 才会生效

 

发布事件

/**
 * 应用上下文
 */
@Autowired
private ApplicationContext applicationContext;

/**
 * 发布事件
 *
 * @param source 事件源
 */
public void publishEvent(Object source) {
    //创建事件
    MyApplicationEvent myApplicationEvent = new MyApplicationEvent(source);
    //发布事件。会自动通知订阅了此事件类型的所有监听器
    applicationContext.publishEvent(myApplicationEvent);
}

标签:自定义,Spring,ApplicationEvent,event,事件驱动,source,事件,监听器,public
来源: https://blog.csdn.net/chy_18883701161/article/details/120387394