【面向接口开发(IOP)典型场景】底层组件如何实现回调通知上层应用系统?

简介: 本文介绍了在账务插件开发中,如何通过“面向接口编程”实现异步转账完成后的回调通知机制。通过定义回调接口 `TransferCallback`,账务组件在异步操作完成后可通知上层应用进行后续业务处理。文章提供了纯 Java 和 Spring 两种实现方式的代码示例,展示了接口在插件化架构中的重要作用,体现了面向接口编程在解耦与扩展方面的优势。




我们在开发一个账务插件(sby-plugin-accounting),将账户的充、转、提等记账功能进行封装,实现复用。

其中,为了提高程序性能,针对账户转账的记账,使用了异步处理:转出账户的扣款在工作线程中执行,而转入账户的入账则采用异步的方式。

那么,现在问题来了,当异步转账完成后,如何通知上层应用层?

没错,达芬奇密码是:面向接口编程(Interface-Oriented Programming, IOP)。通过接口定义插件契约,这是在插件化架构中典型的解决方案。————异步转账完成后,依赖回调接口。上层应用系统如果需要关注异步转账完成的结果,则实现回调接口,进行特定的业务处理。

下面我们列举关键代码,来说明如何基于OOP的IOP思想,通过回调接口实现记账完成的回调通知。下图程序结构是个demo,其中,子包 biz代表上层应用系统的业务逻辑,component 代表底层账务组件;主包 componentdemocomponentdemospring代表纯java版、spring版这两种实现方式。

image.png

🍀纯java版

1. 插件层

●插件中的回调接口TransferCallback

TransferCallback是一个interface类,定义了一个方法onTransferSuccess,这是该插件与上层应用系统建立逻辑关系的纽带。插件中的异步转账调用这个interface,上层应用系统按需实现这个interface

package jstudy.componentdemo.component;

public interface TransferCallback {
   
    void onTransferSuccess();
}

●插件中的转账服务类AccountTransferService

下面AccountTransferService是账务转账服务类(记账逻辑均为示意代码)。其中,

  • 定义了TransferCallback字段,并对外暴露了setter操作;
  • accountingForTos方法中依赖了这个字段的实例,达到转账完成后进行回调通知的目的。
    ```java
    package jstudy.componentdemo.component;

// 转账记账service
@Slf4j
public class AccountTransferService {
private AccountingService accountingService = new AccountingService();
@Setter
private TransferCallback transferCallback;

private static final Executor threadPool = ...;

public void accounting(AccountTransfer accountTransfer) {
    log.info("转账记账开始");
    AccountingRequest accountingRequest = new AccountingRequest(accountTransfer.getTransferOrderNo(), accountTransfer.getFrom(), accountTransfer.getTransferAmount(), true);
    accountingService.accounting(accountingRequest);

    // 通过异步为转账的收款方入账
    threadPool.execute(() -> {
        accountingForTos(accountTransfer);
    });
}

private void accountingForTos(AccountTransfer accountTransfer) {
    var listTo = accountTransfer.getTos();// 收款方集合
    for (var entry: listTo.entrySet()) {
        AccountingRequest accountingRequest = new AccountingRequest(accountTransfer.getTransferOrderNo(), entry.getKey(), entry.getValue(), false);
        accountingService.accounting(accountingRequest);
    }

    boolean isImplementTransferCallback = transferCallback != null;
    log.info("上层应用是否实现了转账回调:{}", isImplementTransferCallback);
    if (isImplementTransferCallback) {
        transferCallback.onTransferSuccess();
    }
}

}


## 2. 上层应用层
下面`TransferOrderService`是应用层的 转账单service 类。该类同时实现了`TransferCallback`接口。 
关键的控制在它的构造器中,决定是否要**开启**转账完成通知。
```java
// 业务转账单service
@Slf4j
public class TransferOrderService implements TransferCallback {
    private AccountTransferService accountTransferService;

    public TransferOrderService() {
        accountTransferService = new AccountTransferService();
//        accountTransferService.setTransferCallback(this);//是否开启转账完成通知
    }

    public void transfer() {
        log.info("转账单记账");

        AccountTransfer accountTransfer = new AccountTransfer();
        accountTransfer.setTransferOrderNo("T202508000001")
                .setFrom("A")
                .setTransferAmount(50.00);
        accountTransfer.setTos(ImmutableMap.of(
                "B", 10.00,
                "C", 40.00));
        accountTransferService.accounting(accountTransfer);
    }

    @Override
    public void onTransferSuccess() {
        log.info("=========当前是在应用层,进行转账完成后的业务处理");
        log.info("=========已向收款人发送到账通知短消息");
    }
}

程序运行结果

  • 开启了转账完成回调
    08:58:49.927 [j.c.biz.TransferOrderService] - 转账单记账
    08:58:49.935 [j.c.component.AccountTransferService] - 转账记账开始
    08:58:49.938 [j.c.component.AccountingService] - AccountingService->记账完成. 业务单号=T202508000001, accountNo=A, amount=50.00
    08:58:49.949 [j.c.component.AccountingService] - AccountingService->记账完成. 业务单号=T202508000001, accountNo=B, amount=-10.00
    08:58:49.949 [j.c.component.AccountingService] - AccountingService->记账完成. 业务单号=T202508000001, accountNo=C, amount=-40.00
    08:58:49.949 [j.c.component.AccountTransferService] - 上层应用是否实现了转账回调:true
    08:58:49.949 [j.c.biz.TransferOrderService] - =========当前是在应用层,进行转账完成后的业务处理
    08:58:49.949 [j.c.biz.TransferOrderService] - =========已向收款人发送到账通知短消息
    
  • 未开启转账完成回调
    08:58:49.927 [j.c.biz.TransferOrderService] - 转账单记账
    08:58:49.935 [j.c.component.AccountTransferService] - 转账记账开始
    08:58:49.938 [j.c.component.AccountingService] - AccountingService->记账完成. 业务单号=T202508000001, accountNo=A, amount=50.00
    08:58:49.949 [j.c.component.AccountingService] - AccountingService->记账完成. 业务单号=T202508000001, accountNo=B, amount=-10.00
    08:58:49.949 [j.c.component.AccountingService] - AccountingService->记账完成. 业务单号=T202508000001, accountNo=C, amount=-40.00
    08:58:49.949 [j.c.component.AccountTransferService] - 上层应用是否实现了转账回调:false
    



🍀spring版

1. 插件层

●插件中的转账服务类AccountTransferService

下面AccountTransferService是账务转账服务类。通过@Autowired(required = false)来注入TransferCallback实例。

package jstudy.componentdemo.component;


// 转账记账service
@Service
@Slf4j
public class AccountTransferService {
   
    @Autowired
    private AccountingService accountingService;
    @Autowired(required = false)
    private TransferCallback transferCallback;

    public void accounting(AccountTransfer accountTransfer) {
   
        ...
        // 通过异步为转账的收款方入账
        threadPool.execute(() -> {
   
            accountingForTos(accountTransfer);
        });
    }

    private void accountingForTos(AccountTransfer accountTransfer) {
   
        ...
        if (isImplementTransferCallback) {
   
            transferCallback.onTransferSuccess();
        }
    }
}

2. 上层应用层

下面TransferOrderService是应用层的 转账单service 类。

由于该类是由 spring 容器托管的 bean,并且实现了TransferCallback接口,因此,这表示开启了转账完成的回调通知。

如果不开启,则不实现TransferCallback接口即可。

// 业务转账单service
@Service
@Slf4j
public class TransferOrderService implements TransferCallback {
   
    @Autowired
    private AccountTransferService accountTransferService;


    public void transfer() {
   
        ...
    }

    @Override
    public void onTransferSuccess() {
   
        ...
    }
}
目录
相关文章
|
22天前
|
算法 Java 测试技术
适合新手小白的史上最强 Java 学习路线图从基础到进阶全程指南
本Java学习路线图涵盖从基础语法、面向对象、集合框架到进阶编程、JVM原理、Spring Boot框架,再到数据库操作与实战项目开发,内容系统全面,适合零基础新手入门与进阶提升,助力掌握Java全栈开发技能。
171 4
|
21天前
|
缓存 小程序 iOS开发
基于uni-app+vue3手机桌面oadmin管理系统
基于uniapp+vue3+pinia2+uv-ui仿ios手机界面oa后台系统解决方案。支持运行到h5+小程序+app端。
113 5
|
30天前
|
消息中间件 Java 测试技术
RocketMQ-5.3.1异常、原因汇总表
本简介汇总了常见的RocketMQ异常信息及其解决方案,涵盖主题配置、网络通信、SSL设置、权限控制、消息发送与消费等多个方面,帮助开发者快速定位和理解异常原因。
177 23
|
23天前
|
安全 Java API
Java中的Lambda表达式:简洁与功能的结合
Java中的Lambda表达式:简洁与功能的结合
173 91
|
22天前
|
运维 监控 测试技术
2025年微服务架构关键知识点(一):核心原则与演进趋势
微服务架构凭借其高可用性、灵活扩展等优势,已成为2025年主流软件开发范式。本文深入解析微服务的核心原则、演进趋势及实践要点,助力开发者夯实基础,应对挑战,构建高效、稳定的系统架构。
|
23天前
|
安全 Java
Java中的Switch表达式:更简洁的多路分支
Java中的Switch表达式:更简洁的多路分支
195 91
|
23天前
|
存储 Java API
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
203 92
|
23天前
|
算法 数据挖掘 测试技术
HiRAG:用分层知识图解决复杂推理问题
HiRAG是一种分层检索增强生成系统,专为复杂知识图的多层推理设计。它通过构建从具体实体到抽象概念的多层次结构,提升知识推理深度与连贯性,有效减少大模型幻觉,适用于天体物理、理论物理等专业领域。
101 3
|
23天前
|
人工智能 API 语音技术
免费版的配音软件,支持童声男声女声不同声音选项,语音转文字软件推荐支持多种声音
免费版的配音软件,支持童声男声女声不同声音选项,语音转文字软件推荐支持多种声音
244 2