基于Java實(shí)現(xiàn)回調(diào)監(jiān)聽工具類
首先,會(huì)用到 函數(shù)式接口 Consumer, 通過這個(gè)可以解耦回調(diào)方法,下面先寫一個(gè)抽象的監(jiān)聽接口
監(jiān)聽接口類 Listenable
import java.util.*;
import java.util.function.Consumer;
public interface Listenable<Listener> {
WeakHashMap<Object, Set> LISTENERS_WEAK_MAP = new WeakHashMap<>();
default void registerListener(Listener listener) {
Objects.requireNonNull(listener);
Set<Listener> listeners;
synchronized (LISTENERS_WEAK_MAP) {
listeners = LISTENERS_WEAK_MAP.get(this);
if (listeners == null) {
listeners = new HashSet<>();
LISTENERS_WEAK_MAP.put(this, listeners);
}
}
synchronized (listeners) {
listeners.add(listener);
}
}
default void unregisterListener(Listener listener) {
Objects.requireNonNull(listener);
Set<Listener> listeners;
synchronized (LISTENERS_WEAK_MAP) {
listeners = LISTENERS_WEAK_MAP.get(this);
if (listeners == null) {
return;
}
}
synchronized (listeners) {
listeners.remove(listener);
}
}
default Collection<Listener> getListeners() {
synchronized (LISTENERS_WEAK_MAP) {
Set<Listener> listeners = LISTENERS_WEAK_MAP.get(this);
if (listeners == null) {
return new HashSet<>();
}
return new HashSet<>(listeners);
}
}
default boolean isListenerRegistered(Listener listener) {
synchronized (LISTENERS_WEAK_MAP) {
Set<Listener> listeners = LISTENERS_WEAK_MAP.get(this);
if (listeners == null) {
return false;
}
return listeners.contains(listener);
}
}
default void forEachListener(Consumer<Listener> action) {
forEachListener(action, true);
}
default void forEachListener(Consumer<Listener> action, boolean ignoreException) {
Objects.requireNonNull(action);
Iterable<Listener> listeners;
synchronized (LISTENERS_WEAK_MAP) {
Set<Listener> values = LISTENERS_WEAK_MAP.get(this);
if (values == null) {
return;
}
listeners = new ArrayList<>(values);
}
for (Listener listener : listeners) {
try {
action.accept(listener);
} catch (Exception e) {
if (!ignoreException) {
throw e;
}
}
}
}
}
實(shí)際用法
用法也比較簡(jiǎn)單,在自己的實(shí)現(xiàn)類 MessageManager 中,寫上自定義的回調(diào) OnEventListener,然后再實(shí)現(xiàn)通知方法,這樣就可以很方便的寫各種需要一對(duì)多通知的不同類型的回調(diào)了
public class Main {
public static class MessageManager implements Listenable<MessageManager.OnEventListener> {
private MessageManager() {}
private static final MessageManager instance = new MessageManager();
public static MessageManager getInstance() {
return instance;
}
public void onSuccess(String json) {
forEachListener(it->it.onSuccess(json));
}
public void onError(int code, String error) {
forEachListener(it->it.onError(code, error));
}
public interface OnEventListener {
void onSuccess(String json);
void onError(int code, String error);
}
}
public static void main(String[] args) {
MessageManager.getInstance().registerListener(new MessageManager.OnEventListener() {
@Override
public void onSuccess(String json) {
System.out.println("onSuccess " + json);
}
@Override
public void onError(int code, String error) {
System.out.println("onError code:" + code + " error:" + error);
}
});
MessageManager.getInstance().onSuccess("My json");
MessageManager.getInstance().onError(-1, "Error");
}
}
打印結(jié)果
onSuccess My json
onError code:-1 error:Error
到此這篇關(guān)于基于Java實(shí)現(xiàn)回調(diào)監(jiān)聽工具類的文章就介紹到這了,更多相關(guān)Java回調(diào)監(jiān)聽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot自動(dòng)掃描包路徑來龍去脈示例詳解
這篇文章主要介紹了Springboot自動(dòng)掃描包路徑來龍去脈示例詳解,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
Java實(shí)現(xiàn)簡(jiǎn)易版聯(lián)網(wǎng)坦克對(duì)戰(zhàn)小游戲(附源碼)
這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)簡(jiǎn)易版聯(lián)網(wǎng)坦克對(duì)戰(zhàn)小游戲的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
IntelliJ Idea SpringBoot 數(shù)據(jù)庫增刪改查實(shí)例詳解
SpringBoot 是 SpringMVC 的升級(jí),對(duì)于編碼、配置、部署和監(jiān)控,更加簡(jiǎn)單。這篇文章主要介紹了IntelliJ Idea SpringBoot 數(shù)據(jù)庫增刪改查實(shí)例,需要的朋友可以參考下2018-02-02
解決@DateTimeFormat格式化時(shí)間出錯(cuò)問題
這篇文章主要介紹了解決@DateTimeFormat格式化時(shí)間出錯(cuò)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
RabbitMQ通過延遲插件實(shí)現(xiàn)延遲消息
在RabbitMQ中,使用延遲消息插件比死信隊(duì)列更優(yōu)化的實(shí)現(xiàn)消息的延遲發(fā)送,本文介紹了延遲插件的下載、安裝、以及如何通過設(shè)置消息頭x-delay實(shí)現(xiàn)消息的延遲投遞,特別指出,使用延遲消息可能會(huì)損耗性能,適合短時(shí)間的延遲場(chǎng)景2024-10-10

