Spring Boot-3-监听器案例

前文中,了解了Spring Boot的系统初始化器,本文再来看一下监听器,监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动. 下面用一个小案例来看一下监听器的具体使用

案例

以一个天气事件为案例,我们一共需要三个元素:

  • 事件
  • 监听器
  • 广播

广播把事件广播出去,然后对应的监听器处理自己感兴趣的事件即可

事件

首先来看一下事件部分的编码,首先创建一个获取天气的抽象类,代码如下:

1
2
3
4
5
6
7
8
9
public abstract class WeatherEvent {

/**
* 获取天气
* @return
*/
public abstract String getWeather();

}

然后写两个实现的子类, 如下:

1
2
3
4
5
6
7
8
public class RainEvent extends WeatherEvent {

@Override
public String getWeather() {
return "Rain";
}

}

1
2
3
4
5
6
7
8
public class SnowEvent extends WeatherEvent {

@Override
public String getWeather() {
return "snow";
}

}

事件部分就是这样,然后看一下监听器的编码

监听器

先写一个接口,然后不同的监听器做对应的实现

1
2
3
4
5
public interface WeatherListener {

void onWeatherListener(WeatherEvent event);

}

然后两个实现类如下:

1
2
3
4
5
6
7
8
9
10
11
@Slf4j
public class RainListener implements WeatherListener {

@Override
public void onWeatherListener(WeatherEvent event) {
if (event instanceof RainEvent) {
log.info("Its {}", event.getWeather());
}
}

}
1
2
3
4
5
6
7
8
9
10
11
@Slf4j
public class SnowListener implements WeatherListener {

@Override
public void onWeatherListener(WeatherEvent event) {
if (event instanceof SnowEvent) {
log.info("Its {}", event.getWeather());
}
}

}

广播

广播部分的实现如下,首先是一个接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public interface EventMulticaster {

/**
* 广播事件
* @param event
*/
void multicastEvent(WeatherEvent event);

/**
* 添加监听器
* @param listener
*/
void addListener(WeatherListener listener);

/**
* 移除监听器
* @param listener
*/
void removeListener(WeatherListener listener);

}

然后写一个抽象的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public abstract class AbstractEventMulticaster implements EventMulticaster{

/**
* 监听器的集合
*/
private List<WeatherListener> listeners = new ArrayList<>();

@Override
public void multicastEvent(WeatherEvent event) {
doStart();
listeners.forEach(x -> x.onWeatherListener(event));
doEnd();
}

@Override
public void addListener(WeatherListener listener) {
listeners.add(listener);
}

@Override
public void removeListener(WeatherListener listener) {
listeners.remove(listener);
}

/**
* 模板方法,广播开始方法
*/
protected abstract void doStart();

/**
* 模板方法,广播结束方法
*/
protected abstract void doEnd();
}

最后是模板方法的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Slf4j
public class WeatherEventMulticaster extends AbstractEventMulticaster {

@Override
protected void doStart() {
log.info("begin broadcast weather event...");
}

@Override
protected void doEnd() {
log.info("end broadcast weather event ...");
}

}

测试

写个测试类,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@SpringBootTest
public class WeatherEventTests {

@Test
public void test() {
// 创建广播
WeatherEventMulticaster multicaster = new WeatherEventMulticaster();

// 创建监听器
RainListener rainListener = new RainListener();
SnowListener snowListener = new SnowListener();

// 添加监听器
multicaster.addListener(rainListener);
multicaster.addListener(snowListener);

// 发送事件
multicaster.multicastEvent(new RainEvent());
multicaster.multicastEvent(new SnowEvent());

// 移除下雨监听器
multicaster.removeListener(rainListener);

// 发送事件
multicaster.multicastEvent(new RainEvent());
multicaster.multicastEvent(new SnowEvent());
}
}

运行,控制台输出如下:

1
2
3
4
5
6
7
8
9
10
11
2020-02-01 18:11:17.945  INFO 17112 --- [    Test worker] c.z.s.e.m.WeatherEventMulticaster        : begin broadcast weather event...
2020-02-01 18:11:17.946 INFO 17112 --- [ Test worker] c.z.s.example.listener.RainListener : Its Rain
2020-02-01 18:11:17.949 INFO 17112 --- [ Test worker] c.z.s.e.m.WeatherEventMulticaster : end broadcast weather event ...
2020-02-01 18:11:17.950 INFO 17112 --- [ Test worker] c.z.s.e.m.WeatherEventMulticaster : begin broadcast weather event...
2020-02-01 18:11:17.950 INFO 17112 --- [ Test worker] c.z.s.example.listener.SnowListener : Its snow
2020-02-01 18:11:17.950 INFO 17112 --- [ Test worker] c.z.s.e.m.WeatherEventMulticaster : end broadcast weather event ...
2020-02-01 18:11:17.950 INFO 17112 --- [ Test worker] c.z.s.e.m.WeatherEventMulticaster : begin broadcast weather event...
2020-02-01 18:11:17.951 INFO 17112 --- [ Test worker] c.z.s.e.m.WeatherEventMulticaster : end broadcast weather event ...
2020-02-01 18:11:17.951 INFO 17112 --- [ Test worker] c.z.s.e.m.WeatherEventMulticaster : begin broadcast weather event...
2020-02-01 18:11:17.951 INFO 17112 --- [ Test worker] c.z.s.example.listener.SnowListener : Its snow
2020-02-01 18:11:17.951 INFO 17112 --- [ Test worker] c.z.s.e.m.WeatherEventMulticaster : end broadcast weather event ...

总结

以一个案例了解一下监听器, 重点就是以下几个要素

  • 事件
  • 监听器
  • 广播器
  • 触发机制