听到监听这个词,不难理解,一个事物根据另一个事物的变化自发的作出响应,而且每次都作出同样的响应。就像点击按钮一样。每次点击登入按钮,都会访问登入接口url,这就是监听。
那么监听需要哪些条件呢。三要素,1.事件2.监听器3.触发动作。点击按钮就是事件,点击之后要怎么处理,就是监听器的事了。那么问题来了,监听器肯定有很多个,每个监听器职责不一样,它们怎么知道要监听哪个事件的。当然是事先就告诉它们了。也就是说在发布事件的时候,所有监听器就已经准备就绪,然后根据事件类型匹配对应监听器。
事实上,spring就是这么干的。
有几个问题:
1.spring的监听器是怎么注册的?在何时注册的?
2.这些事件是如何发布的?
3.事件是怎么找到对应监听器的?
带着这几个问题往下看。。。
先看最简单的一种实现方式。
1.创建一个监听器,实现ApplicationListener接口,泛型中指定事件类型
public class PrintListener implements ApplicationListener<DemoEvent> {
@Override
public void onApplicationEvent(DemoEvent event) {
System.out.println("调用DemoEvent的print方法输出其内容:");
event.print();
}
}
2.创建一个事件,继承ApplicationEvent抽象类
public class DemoEvent extends ApplicationEvent {
private String text;
/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
*/
public DemoEvent(Object source) {
super(source);
}
public DemoEvent(Object source, String text) {
super(source);
this.text = text;
}
public void print() {
System.out.println("print event content:" + this.text);
}
}
3.注册监听器到容器中,发布事件。
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
//注册监听器
context.addApplicationListener(new PrintListener());
//发布事件
context.publishEvent(new DemoEvent(new Object(),"hello world."));
}
}
接下来到源码中去看下。
我们在执行scontext.addApplicationListener的时候,最终走到了一个处理事件的广播类。如下。其实就是把所有的listener加到ListenerRetriever类下的Set集合applicationListeners
public abstract class AbstractApplicationEventMulticaster
implements ApplicationEv