Biz-SIP金融级业务中台(http://bizsip.bizmda.com)是一套基于领域驱动设计(DDD)架构,能快速构建金融级云原生架构的服务整合中间件,整合了在金融场景里锤炼出来的最佳实践。
软件设计的最大目标,就是降低复杂性。万物不为我所有,但万物皆为我用。
如何将复杂的软件系统分解成模块(如类和方法),这些模块可以相对独立的实现?
how to decompose complex software systems into modules (such as classes and methods) that can be implemented relatively independently.
领域驱动设计(DDD)所带来的改变,面向领域设计,面向对象编程,领域模型的抽象就是对现实世界的描述。
xBank是一家商业银行,面向个人客户和公司客户,其中个人客户业务包括存款、贷款、缴费等业务;银行业务渠道除了传统柜面以外,还有网上银行、手机银行、ATM、POS等,最近准备上一个针对银行合作伙伴的基于OPENAPI网关的开放平台渠道。
本示例项目是以个人客户中的存款查询和缴费业务为例子,后台系统对接个人客户存款系统和个人客户信息系统,第三方对接缴费平台,来演示如何打造基于Biz-SIP中间件的银行业务中台。
xbank项目版本库:[https://gitee.com/szhengye/xbank.git]
XmlController是一个RestController应用,主要完成以下处理:
代码如下:
@RestController
@RequestMapping("/personal")
public class XmlController {
// 定义一个接口为PersonalAppInterface的,app层服务名为app/personal的服务调用句柄
private PersonalAppInterface personalAppInterface = SourceClientFactory
.getAppServiceClient(PersonalAppInterface.class,"app/personal");
// 定义一个接口为平台标准JSON接口(类型固定为BizMessageInterface),app层服务名为sink/payment1的服务调用句柄
private BizMessageInterface payment1SinkInterface = SourceClientFactory
.getAppServiceClient(BizMessageInterface.class,"sink/payment1");
// 获取source层消息格式转换器
private Converter converter = Converter.getSourceConverter("xml-source");
@PostMapping(value = "/getCustomerAndAccountList", consumes = "application/xml", produces = "application/xml")
public String getCustomerAndAccountList(@RequestBody String inMessage) throws BizException {
// 消息解包操作
JSONObject jsonObject = this.converter.unpack(inMessage.getBytes());
String customerId = (String)jsonObject.get("customerId");
// 调用app层服务
CustomerAndAccountList customerAndAccountList = this.personalAppInterface.getCustomerAndAccountList(customerId);
jsonObject = JSONUtil.parseObj(customerAndAccountList);
// 消息打包并返回
return new String(this.converter.pack(jsonObject));
}
......
}
XmlController是通过申请App服务的调用接口,在申请调用接口时,会采用App层封装好的App服务Interface接口类:
public class XmlController {
// 定义一个接口为PersonalAppInterface的,app层服务名为app/personal的服务调用接口
private PersonalAppInterface personalAppInterface = SourceClientFactory
.getAppServiceClient(PersonalAppInterface.class,"app/personal");
......
// 调用app层服务
CustomerAndAccountList customerAndAccountList = this.personalAppInterface.getCustomerAndAccountList(customerId);
......
}
在上面的XmlController代码中,App服务调用接口在申请时,会要求填入App层的服务接口类PersonalAppInterface,这是在App层定义的,约定了能被Source层调用的App服务接口,如下所示:
public interface PersonalAppInterface {
public CustomerAndAccountList getCustomerAndAccountList(String customerId);
public List<Account> getAccountListByCustomerId(String customerId);
public Customer getCustomer(String customerId);
public BizMessage send2Payment1(Object message) throws BizException;
public BizMessage send2Payment2(String tranMode, String tranCode, Object message) throws BizException;
public Customer getCustomerAndSaf2Payment2(String tranMode, String customerId) throws BizException;
public Account payout(String accountId,long amount);
public void payoutForward(String tranMode,String accountId,long amount) throws BizException;
public void payoutForwardCompensate(JSONObject jsonObject) throws BizException;
public void payoutBackward(String tranMode,String accountId,long amount) throws BizException;
public void payoutBackwardCompensate(JSONObject jsonObject) throws BizException;
}
PersonalAppService类是上面PersonalAppInterface的具体实现类,服务接口是在类中具体实现的,主要是对Sink层的服务进行服务编排,如下所示:
@Service
public class PersonalAppService implements PersonalAppInterface {
private AccountSinkInterface accountSinkInterface = AppClientFactory
.getSinkClient(AccountSinkInterface.class,"account-sink");
private CustomerSinkInterface customerSinkInterface = AppClientFactory
.getSinkClient(CustomerSinkInterface.class,"customer-sink");
private BizMessageInterface payment1SinkInterface = AppClientFactory
.getSinkClient(BizMessageInterface.class,"payment1-sink");
private BizMessageInterface payment2SinkInterface = AppClientFactory
.getSinkClient(BizMessageInterface.class,"payment2-sink");
private PersonalAppInterface personalAppDelayInterface = AppClientFactory
.getDelayAppServiceClient(PersonalAppInterface.class,"app/personal",
0,1000,2000,4000,8000,16000,32000);
@Override
public CustomerAndAccountList getCustomerAndAccountList(String customerId) {
Customer customer = this.customerSinkInterface.getCustomer(customerId);
List<Account> accountList = this.accountSinkInterface.getAccountListByCustomerId(customerId);
CustomerAndAccountList customerAndAccountList = new CustomerAndAccountList();
customerAndAccountList.setCustomer(customer);
customerAndAccountList.setAccountList(accountList);
return customerAndAccountList;
}
......
}
PersonalAppService类在代码中会申请Sink层服务的调用接口,在申请调用接口时,会采用Sink层封装好的Sink服务Interface接口类:
@Service
public class PersonalAppService implements PersonalAppInterface {
private CustomerSinkInterface customerSinkInterface = AppClientFactory
.getSinkClient(CustomerSinkInterface.class,"customer-sink");
......
Customer customer = this.customerSinkInterface.getCustomer(customerId);
......
}
在上面的PersonalAppService类代码中,Sink服务调用接口在申请时,会要求填入Sink层的服务接口类CustomerSinkInterface,这是在Sink层定义的,约定了能被App层调用的Sink服务接口,如下所示:
public interface CustomerSinkInterface {
public Customer getCustomer(String customerId);
}
CustomerSinkService类是上面的CustomerSinkInterface接口的实现类,具体的Sink服务业务逻辑是在这个类中实现的:
@Service
public class CustomerSinkService implements CustomerSinkInterface {
@Autowired
private CustomerService custmerService;
@Override
public Customer getCustomer(String customerId) {
Customer customer = this.custmerService.getById(customerId);
return customer;
}
}
Biz-SIP网站:http://bizsip.bizmda.com
Gitee代码库:https://gitee.com/szhengye/biz-sip