行业资讯 2025年08月6日
0 收藏 0 点赞 303 浏览 4334 个字
摘要 :

文章目录 一、定义监听接口类Listenable 二、实际用法示例 今天咱们就来聊聊如何用Java实现一个回调监听工具类,借助函数式接口Consumer,可以巧妙地解耦回调方法,这……




  • 一、定义监听接口类Listenable
  • 二、实际用法示例

今天咱们就来聊聊如何用Java实现一个回调监听工具类,借助函数式接口Consumer,可以巧妙地解耦回调方法,这样开发出来的代码结构更清晰、更易于维护。下面,我们一步步来深入了解。

一、定义监听接口类Listenable

首先,我们要创建一个抽象的监听接口Listenable。这个接口的作用是提供一套通用的方法,用于管理和操作监听者。代码如下:

import java.util.*;
import java.util.function.Consumer;

public interface Listenable<Listener> {

    // 使用WeakHashMap来存储监听者,避免内存泄漏,键为当前对象,值为对应监听者的集合
    WeakHashMap<Object, Set> LISTENERS_WEAK_MAP = new WeakHashMap<>();

    // 注册监听者的方法
    default void registerListener(Listener listener) {
        // 检查传入的监听者是否为空,若为空则抛出异常
        Objects.requireNonNull(listener);
        Set<Listener> listeners;
        // 同步访问LISTENERS_WEAK_MAP,确保线程安全
        synchronized (LISTENERS_WEAK_MAP) {
            // 获取当前对象对应的监听者集合
            listeners = LISTENERS_WEAK_MAP.get(this);
            // 如果集合为空,则创建一个新的HashSet
            if (listeners == null) {
                listeners = new HashSet<>();
                // 将新创建的集合存入LISTENERS_WEAK_MAP中
                LISTENERS_WEAK_MAP.put(this, listeners);
            }
        }
        // 同步访问监听者集合,确保线程安全地添加监听者
        synchronized (listeners) {
            listeners.add(listener);
        }
    }

    // 注销监听者的方法
    default void unregisterListener(Listener listener) {
        // 检查传入的监听者是否为空,若为空则抛出异常
        Objects.requireNonNull(listener);
        Set<Listener> listeners;
        // 同步访问LISTENERS_WEAK_MAP,确保线程安全
        synchronized (LISTENERS_WEAK_MAP) {
            // 获取当前对象对应的监听者集合
            listeners = LISTENERS_WEAK_MAP.get(this);
            // 如果集合为空,直接返回,无需进行后续操作
            if (listeners == null) {
                return;
            }
        }
        // 同步访问监听者集合,确保线程安全地移除监听者
        synchronized (listeners) {
            listeners.remove(listener);
        }
    }

    // 获取所有监听者的方法
    default Collection<Listener> getListeners() {
        // 同步访问LISTENERS_WEAK_MAP,确保线程安全
        synchronized (LISTENERS_WEAK_MAP) {
            // 获取当前对象对应的监听者集合
            Set<Listener> listeners = LISTENERS_WEAK_MAP.get(this);
            // 如果集合为空,返回一个空的HashSet
            if (listeners == null) {
                return new HashSet<>();
            }
            // 返回一个包含所有监听者的新HashSet,避免直接返回原集合导致外部修改
            return new HashSet<>(listeners);
        }
    }

    // 检查某个监听者是否已注册的方法
    default boolean isListenerRegistered(Listener listener) {
        // 同步访问LISTENERS_WEAK_MAP,确保线程安全
        synchronized (LISTENERS_WEAK_MAP) {
            // 获取当前对象对应的监听者集合
            Set<Listener> listeners = LISTENERS_WEAK_MAP.get(this);
            // 如果集合为空,说明监听者未注册,返回false
            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;
        // 同步访问LISTENERS_WEAK_MAP,确保线程安全
        synchronized (LISTENERS_WEAK_MAP) {
            // 获取当前对象对应的监听者集合
            Set<Listener> values = LISTENERS_WEAK_MAP.get(this);
            // 如果集合为空,直接返回,无需进行后续操作
            if (values == null) {
                return;
            }
            // 将监听者集合转换为ArrayList,以便进行遍历
            listeners = new ArrayList<>(values);
        }
        // 遍历监听者列表,对每个监听者执行指定操作
        for (Listener listener : listeners) {
            try {
                action.accept(listener);
            } catch (Exception e) {
                // 如果不忽略异常,则抛出捕获到的异常
                if (!ignoreException) {
                    throw e;
                }
            }
        }
    }
}

这个接口定义了一系列方法,包括注册监听者、注销监听者、获取所有监听者、检查监听者是否注册,以及遍历所有监听者并执行指定操作等。通过这些方法,我们可以方便地管理和操作监听者。

二、实际用法示例

了解了监听接口类的定义后,我们来看一下它在实际中的用法。下面以MessageManager类为例,展示如何使用这个监听接口来实现自定义的回调功能。

public class Main {

    // 定义MessageManager类,实现Listenable接口,监听类型为OnEventListener
    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) {
            // 遍历所有监听者,并调用它们的onSuccess方法
            forEachListener(it->it.onSuccess(json));
        }

        // 当操作出错时,通知所有监听者的方法
        public void onError(int code, String error) {
            // 遍历所有监听者,并调用它们的onError方法
            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);
            }
        });

        // 模拟操作成功,调用onSuccess方法通知监听者
        MessageManager.getInstance().onSuccess(\"My json\");
        // 模拟操作出错,调用onError方法通知监听者
        MessageManager.getInstance().onError(-1, \"Error\");
    }
}

在这个示例中,MessageManager类实现了Listenable接口,并定义了自己的监听者接口OnEventListener,包含onSuccessonError两个回调方法。在main方法中,我们注册了一个监听者,并分别调用onSuccessonError方法,模拟操作成功和出错的情况,观察监听者的回调处理。运行代码后,控制台会输出以下结果:

onSuccess My json
onError code:-1 error:Error

这表明我们成功实现了回调监听功能,当MessageManager中的操作状态发生变化时,注册的监听者能够及时收到通知并执行相应的处理逻辑。

通过上述步骤,我们成功实现了一个Java回调监听工具类,并展示了它的实际用法。这种方式可以帮助我们在开发过程中,更好地实现对象间的事件通信,提高代码的灵活性和可维护性。希望大家通过这篇文章,对Java的回调监听机制有更深入的理解和掌握。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/10520.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

986
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

463
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

347
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

455
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

516
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

831
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号