监听者通过向发布者注册自身(自身可以理解为监听者对象),如果有事件发生,发布者会调用注册列表里的监听者的某方法并把事件(事件内部持有事件源)作为参数传入。
在Spring中需要我们自己定义事件监听器、事件。发布器不需要自定义,但需要设法通过上下文拿到发布器。(可以思考下为什么这么设计?)
EventObject:是JDK自带的事件,是个具体的类,本身持有一个Object事件源用来定义本次事件的具体描述。EventObject本身是事件源的容器。
ApplicationEvent:是对EventObject的简单封装(扩展),但是是个抽象类,用来作为自定义事件类的基类,这样设计也是为了满足对监听器对具体某自定义事件的监听。该类构造函数里调用了super(source)用来封装事件源,并提供了一个返回当前时间的方法。
MySpringApplicationEvent:是自定义的事件类,也是本次讲解中要被监听的事件。其构造函数需要的参数同样是自定义的事件源。
Aware是个空接口,用来方便扩展,也是Spring的惯用操作
ApplicationEventPublisherAware是Spring中用来识别注入ApplicationEventPublisher对象的特殊接口。(一般xxxxxAware都是用来给实现类注入xxxxx的)
MySpringEventPublisherContext是自定义的发布者容器,里面封装了Spring提供的事件发布器
EventListener:Spring提供的空接口
ApplicationListener:继承了EventListener且通过使用泛型来实现针对某一具体事件类型的监听,onApplicationEvent作为事件触发时调用的函数。
MyEventSource是事件源的具体实现,是事件的核心内容,该类持有大部分有效信息。
1、MyEventSource.java
/** * 用来描述事件源的实体类 */ public class MyEventSource implements Serializable { private static final long serialVersionUID = 1L; private int id; private String name; public MyEventSource(int id, String name) { this.id = id; this.name = name; } @Override public String toString() { return "MyEventSource{" + "id=" + id + ", name='" + name + '\'' + '}'; } }2、MySpringApplicationEvent.java
import org.springframework.context.ApplicationEvent; /** * 使用spring事件框架自定义的事件 */ public class MySpringApplicationEvent extends ApplicationEvent { public MySpringApplicationEvent(MyEventSource eventSource) { super(eventSource); } }3、MySpringApplicationListener.java
import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Service; /** * 基于Spring事件框架自定义的事件监听器,注意泛型用来确定要监听的事件 */ @Service public class MySpringApplicationListener implements ApplicationListener<MySpringApplicationEvent> { @Override public void onApplicationEvent(MySpringApplicationEvent mySpringApplicationEvent) { System.out.println("监听到事件:"+mySpringApplicationEvent.getSource().toString()); } }4、MySpringEventPublisherContext.java
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.stereotype.Service; /** * 事件发布器上下文 */ @Service public class MySpringEventPublisherContext implements ApplicationEventPublisherAware { private ApplicationEventPublisher applicationEventPublisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { System.out.println("注入事件发布器"); this.applicationEventPublisher = applicationEventPublisher; } public ApplicationEventPublisher getApplicationEventPublisher() { return applicationEventPublisher; } }5、TestSpringEventMain.java
import org.springframework.context.support.ClassPathXmlApplicationContext; /** * 测试SpringEvent的启动器 */ public class TestSpringEventMain { public static void main(String[] args) { System.out.println("1、加载spring容器"); ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("application.xml"); System.out.println("2、从容器中获取事件发布器"); MySpringEventPublisherContext publisherContext = classPathXmlApplicationContext.getBean(MySpringEventPublisherContext.class); System.out.println("3、发布事件"); publisherContext.getApplicationEventPublisher().publishEvent(new MySpringApplicationEvent(new MyEventSource(1,"daquan"))); } }6、配置文件 application.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <context:annotation-config /> <!--自动扫描含有@Service将其注入为bean --> <context:component-scan base-package="com.daquan._202007" /> </beans>运行5、结果如下: