有些时候我们在进行接口调用的时候,比如说一个push推送接口,有可能会涉及到不同渠道的推送,以我目前业务场景为例,我做结算后端服务的,会与金蝶财务系统进行交互,那么我结算后端会涉及到多个结算单类型,如果每一个种类型的结算单都去暴露一个contoller接口给前端提供,而且其实对接第三方的接口,有些接口是共通的;
大致的流程图就是这样的
Tps服务暴露feign接口,前端统一通过Tps提供的接口进行调用
- //对接第三方服务接口
- public interface IKingdeeManagementService {
- Boolean push(KingdeePushCO.Request request);
- }
Feign接口实现类
- @Slf4j
- @Service
- public class KingdeeManagementServiceImpl implements IKingdeeManagementService {
-
- @Autowired
- private ApplicationContext applicationContext;
- @Autowired
- private KingdeeThirdSettingService kingdeeThirdSettingService;
-
- @Override
- public Boolean push(KingdeePushCO.Request request) {
-
- KingdeeBusinessPushServiceEnum kingdeePushServiceEnum = KingdeeBusinessPushServiceEnum.getKingdeePushServiceEnumByType(request.getBusinessType());
-
- IKingdeeBusinessPushService kingdeePushService = null;
- try {
- kingdeePushService = (IKingdeeBusinessPushService) applicationContext.getBean(kingdeePushServiceEnum.getClazz());
- } catch (BeansException e) {
- log.error("当前类型暂未实现,请联系开发");
- throw new ServiceException("当前类型暂未实现,请联系开发");
- }
- R
result = null; - result = kingdeePushService.pushKingdee(request);
-
-
- return true;
- // }
- }
- }
枚举类定义
- public enum KingdeeBusinessPushServiceEnum {
-
- private Class clazz;
-
- private Integer type;
-
- private String interFaceName;
-
- KingdeeBusinessPushServiceEnum(Class clazz, Integer type, String interFaceName) {
- this.clazz = clazz;
- this.type = type;
- this.interFaceName =interFaceName;
- }
- RECEIPT_VOUCHER(IJaKingdeeBillClient.class,KingdeeBusinessTypeConstant.RECEIPT_VOUCHER, KingdeeSettingEnum.INTERFACE_TYPE_JA_RECEIPT_VOUCHER.getCode()),
- ;
- }
分别有clazz、type、interFaceName属性,
拿bms服务举例说明: 继承Tps服务的feign接口,重写push方法;
Feign接口实现,通过factory工厂类初始化,不同的service实现类;
JaKingdeeFactoryUtil 工厂工具类,获取工厂实例,这里其实也可以使用枚举映射,避免以后接口太多,需要写很多case when;
JaKingdeeServiceFactory是个接口,提供方法;
实现上面的接口,通过单例工厂的模式double check的模式实现,并且加悲观锁,避免一个工作线程多次创建工厂实例,SpringContextUtils./getBean/获取servcie实例,业务层只需要实现service接口,实现不同业务逻辑的push推送方法;
这是我之前设计的关于接口统一调用的流程,当然其实还是包括对接第三方重复调用的问题、调用结果缓存、调用超时解决、失败降级的一些策略,如果还有更好的接口统一调用方式欢迎大家评论区留言讨论;