一、监听器模式介绍
当我们的系统运行在一定的关键节点的时候,它会通过广播器发布这些事件出去,而我们系统中存在着部分监听器,他对某些关键节点的事件是感兴趣的,所以他会去订阅这部分消息,当这些事件被发布出去之后,他们就会监听到这些事件,从而去触发一些行为。
实例:创建一个下雪下雨监听器
1.定义一个天气事件,抽象类,抽象方法:获得当前的天气
package com.gf.springboot.event;
public abstract class WeatherEvent {
public abstract String getWeather();
}
2.定义两个事件,一个是下雪,一个是下雨,继承天气事件,重写方法
package com.gf.springboot.event;
public class RainEvent extends WeatherEvent {
@Override
public String getWeather() {
return "rain";
}
}
package com.gf.springboot.event;
public class SnowEvent extends WeatherEvent {
@Override
public String getWeather() {
return "snow";
}
}
3.定义一个天气的事件监听器, 先定义一个接口,定义一个事件:当它监听到天气的时候做出的行为
package com.gf.springboot.event;
public interface WeatherListener {
void onWeatherEvent(WeatherEvent event);
}
4.写两个监听器,下雪监听器,实现上述接口,重写方法:如果天气是下雪天气的时候,打印下雪。下雨监听器,同上
package com.gf.springboot.event;
import org.springframework.stereotype.Component;
@Component
public class RainListener implements WeatherListener{
@Override
public void onWeatherEvent(WeatherEvent event) {
if(event instanceof RainEvent){
System.out.println("hello "+event.getWeather());
}
}
}
package com.gf.springboot.event;
import org.springframework.stereotype.Component;
@Component
public class SnowListener implements WeatherListener{
@Override
public void onWeatherEvent(WeatherEvent event) {
if(event instanceof SnowEvent){
System.out.println("hello "+event.getWeather());
}
}
}
5.定义一个广播器,定义广播器的接口,定义几个方法:广播事件,添加监听器,删除监听器,
package com.gf.springboot.event;
public interface EventMulticaster {
void multicastEvent(WeatherEvent event);
void addListener(WeatherListener weatherListener);
void removeListener(WeatherListener weatherListener);
}
6.定义一个抽象类,实现接口,重写方法。定义监听器的集合,定义模板方法:写两个抽象方法,让具体实现类去做相应的事情(模板设计方法)
package com.gf.springboot.event;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractEventMulticaster implements EventMulticaster {
private List<WeatherListener> listenerList = new ArrayList<>();
@Override
public void multicastEvent(WeatherEvent event) {
doStart();
listenerList.forEach(i->i.onWeatherEvent(event));
doEnd();
}
@Override
public void addListener(WeatherListener weatherListener) {
listenerList.add(weatherListener);
}
@Override
public void removeListener(WeatherListener weatherListener) {
listenerList.remove(weatherListener);
}
abstract void doStart();
abstract void doEnd();
}
编写监听器的触发,编写添加监听器,移除监听器
完成抽象类的实现,对接口的基本方法做了管理,具体实现类只要完成模板方法中的抽象方法即可
7.定义一个天气广播器类,继承抽象类,重写抽象方法
package com.gf.springboot.event;
import org.springframework.stereotype.Component;
@Component
public class WeatherEventMulticaster extends AbstractEventMulticaster {
@Override
void doStart() {
System.out.println("begin broadcast weather event");
}
@Override
void doEnd() {
System.out.println("end broadcast weather event");
}
}
8.编写测试类,构造广播器,定义两个监听器的实例,将监听器添加到广播器当中,通过广播器添加事件
package com.gf.springboot.event;
public class test {
public static void main(String[] args) {
WeatherEventMulticaster eventMulticaster = new WeatherEventMulticaster();
SnowListener snowListener = new SnowListener();
RainListener rainListener = new RainListener();
eventMulticaster.addListener(snowListener);
eventMulticaster.addListener(rainListener);
eventMulticaster.multicastEvent(new SnowEvent());
eventMulticaster.multicastEvent(new RainEvent());
eventMulticaster.removeListener(rainListener);
eventMulticaster.multicastEvent(new SnowEvent());
eventMulticaster.multicastEvent(new RainEvent());
}
}
监听器模式要素:事件,监听器,广播器,触发机制
二、系统监听器介绍
系统监听器ApplicationListener
实现这个接口的时候可以声明你对哪些事件感兴趣,系统在触发监听器的时候会根据感兴趣的事件做一个过滤,有一个方法:当它监听到事件发生的时候去执行什么事情,需要在具体的实现类中重写该方法
系统广播器ApplicationEventMulticaster
有添加监听器,删除监听器,广播事件方法
系统事件
spring boot中有哪些关键阶段会发送事件,发送事件的顺序是?
监听器注册
4种方式,前三种类似系统初始化器的注册方式
三、监听事件触发机制
starting 内部调用广播器发送ApplicationStartingEvent事件
springboot容器通过这种机制使得监听器的内部实现与外部调用隔离开,springboot在运行只需要调用这个类的各个关键方法即可,不需要自己去构造相应的事件发送
动手模拟spring boot容器实现,新构造一个类,使得外部只需调用接口即可
package com.gf.springboot.event;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class WeatherRunListener {
@Autowired
private WeatherEventMulticaster eventMulticaster;
public void snow(){
eventMulticaster.multicastEvent(new SnowEvent());
}
public void rain(){
eventMulticaster.multicastEvent(new RainEvent());
}
}
添加注解
package com.gf.springboot.event;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public abstract class AbstractEventMulticaster implements EventMulticaster {
@Autowired
private List<WeatherListener> listenerList;
@Override
public void multicastEvent(WeatherEvent event) {
doStart();
listenerList.forEach(i -> i.onWeatherEvent(event));
doEnd();
}
@Override
public void addListener(WeatherListener weatherListener) {
listenerList.add(weatherListener);
}
@Override
public void removeListener(WeatherListener weatherListener) {
listenerList.remove(weatherListener);
}
abstract void doStart();
abstract void doEnd();
}
测试
package com.gf.springboot;
import com.gf.springboot.event.WeatherRunListener;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootApplicationTests {
@Autowired
private WeatherRunListener weatherRunListener;
@Test
void contextLoads() {
}
@Test
public void testWeather(){
weatherRunListener.snow();
weatherRunListener.rain();
}
}
四、自定义监听器实战
五、总结
介绍下监听器模式?
SpringBoot关于监听器相关的实现类有哪些?
SpringBoot框架有哪些框架事件以及它们的顺序?
介绍下监听事件触发机制?
如何自定义实现系统监听器及注意事项?
实现ApplicationListener接口与SmartApplicationListener接口区别?