最近在看 springboot 的源码;在关于 事件处理模块,发现了除了使用工厂模式外还是用了监听器模式。
之前没有弄过,于是拜访度娘学习了下。
简介
监听器模式有三个要素 —— 广播器、事件、监听器
广播器:用于事件注册和广播
事件:触发的操作
监听器:监听器模式的核心,定义事件发生后的动作
代码示例
事件
//定义一个天气事件抽象类;抽象类、接口随便个人喜欢
public abstract class WeatherEvent {
public abstract String getWhether();
}
//具体天气事件-下雪
public class SnowWeatherEvent extends WeatherEvent {
@Override
public String getWhether() {
return "snow";
}
}
//具体天气事件-下雨
public class RainWeatherEvent extends WeatherEvent {
@Override
public String getWhether() {
return "rain";
}
}
监听器
//定义事件监听器接口
public interface WeatherListener {
void onWeatherExevt(WeatherEvent weatherEvent);
}
//事件监听器实现-监听下雨事件
public class RainWeatherListener implements WeatherListener {
@Override
public void onWeatherExevt(WeatherEvent weatherEvent) {
if (weatherEvent instanceof RainWeatherEvent){
System.out.println("rain listen");
}
}
}
//事件监听器实现-监听下雪事件
public class SnowWeatherListener implements WeatherListener {
@Override
public void onWeatherExevt(WeatherEvent weatherEvent) {
if (weatherEvent instanceof RainWeatherEvent){
System.out.println("snow listen");
}
}
}
广播器
//定义事件广播器接口
public interface EventMulticaster {
//广播事件
void multicasterEvent(WetherEvent wetherEvent);
//添加事件
void addListener(WetherListener wetherListener);
//移除事件
void removeListener(WetherListener wetherListener);
}
//事件广播器接口实现类
public class WeatherEventMulticaster implements EventMulticaster {
//全局:用于存储监听器
private List<WetherListener> weatherListenerList = new ArrayList<>();
@Override
public void multicasterEvent(WetherEvent wetherEvent) {
for (WetherListener wetherListener : weatherListenerList) {
wetherListener.onWetherExevt(wetherEvent);
}
}
@Override
public void addListener(WetherListener wetherListener) {
weatherListenerList.add(wetherListener);
}
@Override
public void removeListener(WetherListener wetherListener) {
weatherListenerList.remove(wetherListener);
}
}
测试
public class TestListener {
public static void main(String[] args) {
//时间广播器
WeatherEventMulticaster weatherEventMulticaster = new WeatherEventMulticaster();
//创建下雨、下雪两个监听
RainWetherListener rainWetherListener = new RainWetherListener();
SnowWetherListener snowWetherListener = new SnowWetherListener();
//添加监听器
weatherEventMulticaster.addListener(rainWetherListener);
weatherEventMulticaster.addListener(snowWetherListener);
//下雨、下雪事件广播
weatherEventMulticaster.multicasterEvent(new RainWetherEvent());
weatherEventMulticaster.multicasterEvent(new SnowWetherEvent());
System.out.println("--------------------------------------------");
//移除下雨监听
weatherEventMulticaster.removeListener(rainWetherListener);
//下雨、下雪事件广播
weatherEventMulticaster.multicasterEvent(new RainWetherEvent());
weatherEventMulticaster.multicasterEvent(new SnowWetherEvent());
}
}
打印结果:
rain listen
snow listen
--------------------------------------------
snow listen
这里测试使用的 TestListener 中的 main方法耦合性太高,结合 springboot 框架使用下。
//修改 WeatherEventMulticaster 广播器
@Component
public class WeatherEventMulticaster implements EventMulticaster {
//项目启动的时候,spring会自动加载WetherListener 实现bean类,所以等会把监听器也交给spring 管理
@Autowired
private List<WetherListener> weatherListenerList;
@Override
public void multicasterEvent(WetherEvent wetherEvent) {
for (WetherListener wetherListener : weatherListenerList) {
wetherListener.onWetherExevt(wetherEvent);
}
}
@Override
public void addListener(WetherListener wetherListener) {
weatherListenerList.add(wetherListener);
}
@Override
public void removeListener(WetherListener wetherListener) {
weatherListenerList.remove(wetherListener);
}
}
//加上 Component 注解,使其作为spring 的bean初始化
@Component
public class RainWetherListener implements WetherListener {
@Override
public void onWetherExevt(WetherEvent wetherEvent) {
if (wetherEvent instanceof RainWetherEvent){
System.out.println("rain listen");
}
}
}
@Component
public class SnowWetherListener implements WetherListener {
@Override
public void onWetherExevt(WetherEvent wetherEvent) {
if (wetherEvent instanceof RainWetherEvent){
System.out.println("snow listen");
}
}
}
@Component
public class WeatherRunListtener {
@Autowired
private WeatherEventMulticaster weatherEventMulticaster;
public void snow(){
weatherEventMulticaster.multicasterEvent(new SnowWetherEvent());
}
public void rain(){
weatherEventMulticaster.multicasterEvent(new RainWetherEvent());
}
}
@SpringBootApplication
public class NettyTestApplication implements CommandLineRunner {
@Autowired
private WeatherRunListtener weatherRunListtener;
public static void main(String[] args) {
SpringApplication.run(NettyTestApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
weatherRunListtener.rain();
weatherRunListtener.snow();
}
}