监听器模式之从函数式编程到Spring bean注入

文章探讨了在Java中如何使用函数式编程实现监听器模式,包括无规范的BiConsumer接口和SpringBean下的IProcessListener接口。还讨论了监听器的同步异步执行,以及如何在Spring中利用线程池进行控制。
摘要由CSDN通过智能技术生成

从上一篇“java自定义函数”已经了解到函数式编程也能做到依赖反转,也已经清晰的看到了监听器模式的编码方式。

下面我们看看这种监听器模式可以有几种写法。

我们以流程引擎处理流程为例

public class ProcessManager {

    public void doProcess(Process process, User user) {
        // 用户处理流程
        System.out.println("流程已正常处理完成");
        // 后面可能要发信息通知申请的人
    }
}

函数监听器模式

public class ProcessManager {
    // 流程成功时的监听器
    public static final List<BiConsumer<Process, User>> PROCESS_SUCCESS_LISTENERS = new ArrayList<>();

    public void doProcess(Process process, User user) {
        // 用户处理流程
        System.out.println("流程已正常处理完成");
        // 后面可能要发信息通知申请的人,
        // 这里将所有的监听器都执行一次,异常情况暂时忽略
        PROCESS_SUCCESS_LISTENERS.forEach(l -> l.accept(process, user));
    }
}

这样我们可能需要在main函数,或spring启动后,或在外部请求时加入监听者

public static void main(String[] args) {
        ProcessManager.PROCESS_SUCCESS_LISTENERS.add((p, u) ->
                System.out.println(String.format("用户%s 批准了%s的申请", u.getName(), p.getApplyUser().getName()))
        );
    }

当ProcessManager.doProcess完毕后,就会调用main函数中注册的函数式代码。

函数式监听器看起来比较没有规范,到处可以使用简短的函数即可添加监听器,而且监听器没有名字。如果我们需要更规范化的定义方式,那其实只需要将BiConsumer使用自定义接口替换即可

Spring bean监听器模式

// 定义接口
public interface IProcessListener {
    public void notice(Process process, SecurityProperties.User user);
}
// 定义实现
public class NoticeListener implements IProcessListener {
    @Override
    public void notice(Process process, SecurityProperties.User user) {
        System.out.println(String.format("用户%s 批准了%s的申请", u.getName(), p.getApplyUser().getName()))
    }
}

// 修改流程引擎中的定义
// 流程成功时的监听器
    public static final List<IProcessListener> PROCESS_SUCCESS_LISTENERS = new ArrayList<>();

如果ProcessManager, NoticeListener 都是spring bean的话

可以使用自动注入

// 流程成功时的监听器
    @Autowired
    private List<IProcessListener> PROCESS_SUCCESS_LISTENERS;

监听器同步异步执行

spring自带的监听器中对事件的处理,有同异步之分,这里其实也就是把如下代码使用线程池包装一下即可。特别要注意的是线程池的队列配置与拒绝策略,避免异步执行时报错影响主线程。

// 这里将所有的监听器都执行一次,异常情况暂时忽略
        PROCESS_SUCCESS_LISTENERS.forEach(l -> l.accept(process, user));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值