当前位置: 首页 > news >正文

OpenAPI SDK组件介绍

背景

公司成立以来,积累了数以万计的可复用接口。上层的SaaS业务,原则上要复用这些接口开发自己的业务,为了屏蔽调用接口的复杂性,基础服务开发了apisdk组件,定义了一套声明OpenAPI的注解、注解解析器,实例化OpenAPI的工具,封装了签名算法,同时提供了查询域名、查询参与签名的secret、获取Token等基础服务。不同场景的OpenAPI,如App端和Web端,需要调用不同的基础服务。

这套apisdk组件经过了多年的应用,功能上完全hold住业务需求,然而问题来了。

公司在疫情这几年的经济效益实在太差,我做这期分享前,裁了50%(可能有人猜到是哪家公司),当然大多数的互联网公司都有裁员的动作。那裁员之后的业务谁来做?公司战略是交给外包。

但是我们的业务完全依赖基础服务的自研网关、用户体系、接口暴露组件、apisdk组件、基础服务等,外包要承接业务,必须要学会这套东西。但这些东西封装的并不完善,简单来说,都不是傻瓜式的,对外包来说成本太高。别说外包了,业务部门说直白一点,是面向接口编程,对新入职的同学,学习成本高,开发效率低。

于是,为了让一切变得傻瓜式,我承担了网关接口暴露组件、apisdk的二次封装。此次分享内容主要以apisdk为主,涉及的技术/内容:Springboot拓展点的应用、自定义Spring扫描、Spring IoC(FactoryBean)、JDK动态代理、aop源码拓展、javassist字节码技术等。

注:分享的源码全部是自己代码,借鉴了Spring注解、aop等源码,不含公司成分,目的是分享这些技术的实战。

apisdk组件

apisdk组件包括了开放接口声明、签名算法、Http执行器(okhttp3)、响应数据解析等模块,其中接口声明、参与签名的参数需要开发者提供,开发者调用接口方法,触发Http执行器发起接口调用。

二次封装原因:除了学习成本高,它还是java和kotlin混用,原作者早已离职,维护困难,只能在原基础上做封装。

下面截图是原始的apisdk和二次封装后的apisdk使用方式的对比,通过截图,大家会对开放接口的声明、请求上下文构建、接口调用方式有一定的认识,有助于大家理解屏蔽了哪些操作。

接口声明

原接口声明

在这里插入图片描述
接口声明必须要有SdkContext固定参数,接口调用前,必须手动调用基础服务构造SdkContext上下文,这样才能正确的发起调用。

二次封装后接口声明

在这里插入图片描述
二次封装后,由底层完成了SdkContext参数的自动填充。

接口调用

原调用方式

在这里插入图片描述
上面是模拟调用的过程,包括接口实例化、SdkContext封装、接口调用,实际的调用过程比这个复杂的多。

二次封装后接口调用方式

在这里插入图片描述

apisdk二次封装介绍

二次封装涉及到的技术:自定义自动装配、自定义Spring扫描、Spring IoC(FactoryBean)、JDK动态代理、aop源码拓展、javassist字节码技术等。下面简单的介绍下二开的思路及相关的技术点。

思路

原始接口声明必须要定义SdkContext参数,必须要手动调用多个服务创建SdkContent,必须要手动声明接口实例。据我了解:

  • 公司不允许跨区域(域名)调用开放接口,如不允许中国区调用美国区暴露的接口。
  • 调用开放接口一定要有SdkContext参数
  • SdkContext构建的步骤是固定的,但涉及的服务较多

综上,域名问题可以通过部署环境动态获取(已有服务);开发者可以不定义SdkContext参数,底层通过字节码技术动态新增SdkContext方法参数;底层拓展aop的advice,方法执行前构建SdkContext参数;实现Spring扫描组件,通过FactoryBean实例化接口,开发者使用注解即可完成Bean对象的依赖。

涉及技术

自定义自动装配

自研boot启动器,主要是@Import的应用,在apisdk中是Spring自定义扫描的入口。

自定义Spring扫描

利用Spring扫描,把开放接口的声明解析成BeanDefinition,随后由Spring进行Bean的实例化。

apisdk自研框架与Spring整合(FactoryBean)

开放接口的BeanDefinition是接口,无法实例化,因此需要替换BeanDefinition的beanClass,由FactoryBean触发Bean的实例化,生成代理对象,通过FactoryBean#getObject方法将代理对象注册到IoC中。

javassist字节码

FactoryBean生成开放接口(A)的代理对象前,使用javassist生成全新的内存类(B),复制A的方法,并在每个方法上添加SdkContext参数,这样形成了A和B的映射关系。

Jdk动态代理

原始接口A和内存接口B,他们的实例化必须由动态代理支持,A和B的代理对象是怎么样的关系?

开发者使用A的代理对象,调用的方法都是没有SdkContext方法的,底层真正执行时,会围绕对象A做一些列的拦截动作,得到SdkContext,随后底层拿到B对象,调用方法并传递SdkContext。

上面对比的截图,读者知道有SdkManager可以生成接口的代理对象,二次封装后,我提供了JdkDynamicAopProxy,A和B对象由这两个工具来生成代理,SdkManager生成B的对象,JdkDynamicAopProxy生成A的对象,并且A对象由一些列的拦截动作。

Aop源码拓展

二次封装最重要的是:在A对象的方法执行过程中前置拦截,生成SdkContext,并调用B对象。拦截的实现是抽取Spring aop的api,形成独立的Api,目的是离开Spring仍然可以运行。

Aop的变动包括:扩展MethodBeforeArgsChangeableAdvice参数可变的前置拦截,动态构建方法参数。

其他

Environment

FactoryBean&property-placeholder
EnvironmentPostProcessor
ApplicationContextInitializer

BeanFactoryPostProcessor

工程结构

在这里插入图片描述
工程结构如上图,其中

  • access-boot-apisdk:模拟apisdk,包括OpenAPI声明注解、注解解析器,实例化OpenAPI的工具,封装了签名算法等
  • access-boot-autoconfigure:apisdk二次封装核心
  • access-boot-dependencies:依赖管理
  • access-boot-starter-sample:业务开发Demo
  • access-boot-starters:启动器依赖

分享内容来自此工程,大家请参考 码云。

注意

之后的blog,我会按照以下规则介绍。

  • 开发者定义的接口声明,我称作为原始接口、A接口、A

  • javassist生成的接口声明,我称作为增强接口、内存接口、B接口、B

相关文章:

OpenAPI SDK组件介绍

背景 公司成立以来,积累了数以万计的可复用接口。上层的SaaS业务,原则上要复用这些接口开发自己的业务,为了屏蔽调用接口的复杂性,基础服务开发了apisdk组件,定义了一套声明OpenAPI的注解、注解解析器,实例…...

【Java】Synchronized锁原理和优化

一、synchronized介绍 synchronized中文意思是同步,也称之为”同步锁“。 synchronized的作用是保证在同一时刻, 被修饰的代码块或方法只会有一个线程执行,以达到保证并发安全的效果。 synchronized是Java中解决并发问题的一种最常用的方法…...

西北工业大学2020-2021学年大物(I)下期末试题选填解析

2 位移电流。磁效应服从安培环路,热效应不服从焦耳-楞次定律。注意,它是变化的电场而非磁场产生。3 又考恒定磁场中安培环路定理。4感生电场5 麦克斯韦速率分布函数。6 相同的高温热源和低温热源之间的一切可逆热机的工作效率相等,无论工质如…...

PHP - ChatGpt API 接入 ,代码,亲测!(最简单!)

由于最近ChatGpt 大火,但是门槛来说是对于大家最头疼的环节, 我自己也先开发了一个个人小程序!大家可以访问使用下, 由此ChatGpt 有一个API 可以仅供大伙对接 让我来说下资质: 1:首先要搞得到一个 ChatGp…...

物联网MQTT协议简单介绍

物联网曾被认为是继计算机、互联网之后,信息技术行业的第三次浪潮。随着基础通讯设施的不断完善,尤其是 5G 的出现,进一步降低了万物互联的门槛和成本。物联网本身也是 AI 和区块链应用很好的落地场景之一,各大云服务商也在纷纷上…...

Dubbo 源码解读:负载均衡策略

概览 org.apache.dubbo包下META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.LoadBalance中内部spi实现类有以下几种: randomorg.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance roundrobinorg.apache.dubbo.rpc.cluster.loadbalance.RoundRobinL…...

吃瓜教程笔记—Task04

神经网络 知识点 M-P神经元 模型如图所示:  神经元的工作机理:神经元接收来到n个其他神经元传递过来的输入信号,这些输入信号通过带权重的连接进行传递,神经元接收到的总输入值将与神经元的阈值进行比较,然后通过…...

进程地址空间(虚拟地址空间)

目录 引入问题 测试代码 引入地址空间 故事1: 故事二: 解决问题 为什么有虚拟地址空间 扩展 扩展1(没有地址空间,OS如何工作) 扩展2 (代码只读深入了解) 扩展3(malloc本质…...

【项目精选】基于Vue + ECharts的数据可视化系统的设计与实现(论文+源码+视频)

今天给小伙伴们推荐一款超优秀的全新Vue3.0大数据系统Vue3-bigData。 点击下载源码 vue3-bigdata 基于vue3.0echarts构建的可视化大屏图表展示系统。包括各种可视化图表及Vue3新API使用。 功能 柱状图、饼图、词云图、漏斗图 水球图、折线图 仪表盘、雷达图 矩形树图、关系…...

JavaScript Window Screen

文章目录JavaScript Window ScreenWindow ScreenWindow Screen 可用宽度Window Screen 可用高度JavaScript Window Screen window.screen 对象包含有关用户屏幕的信息。 Window Screen window.screen对象在编写时可以不使用 window 这个前缀。 一些属性: screen…...

【双重注意机制:肺癌:超分】

Dual attention mechanism network for lung cancer images super-resolution (肺癌图像超分辨率的双重注意机制网络) 目前,肺癌的发病率和死亡率均居世界恶性肿瘤之首。提高肺部薄层CT的分辨率对于肺癌筛查的早期诊断尤为重要。针对超分辨…...

各种中间件的使用

init background 这一部分我们学习一些常用的, 但是不需要深入理解的中间件 , 例如kafka ,分布式文件系统。 summary Content what is kafka? What time to used it ? 其实消息队列就是解决系统之间复杂交互例如聊天系统和交易系统, …...

Systemverilog覆盖率的合并和计算方式

在systemverilog中,对于一个covergroup来说,可能会有多个instance,我们可能需要对这些instance覆盖率进行操作。 只保存covergroup type的覆盖率,不需要保存instance-specified的覆盖率coverage type和instance-specified的覆盖率…...

(周末公众号解读系列)2000字-视觉SLAM综述

参考链接:https://mp.weixin.qq.com/s?__bizMzg2NzUxNTU1OA&mid2247528395&idx1&sn6c9290dd7fd926f11cbaca312fbe99a2&chksmceb84202f9cfcb1410353c805b122e8df2e2b79bd4031ddc5d8678f8b11c356a25f55f488907&scene126&sessionid1677323905…...

力扣29-两数相除

29. 两数相除 给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。 整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 &#x…...

【MindSpore】安装和使用MindSpore 2.0.0版本简单实现数据变换Transforms功能

本篇文章主要是讲讲MindSpore的安装以及根据官方提供的例子实现数据变换功能。 昇思MindSpore是一款开源的AI框架,旨在实现易开发、高效执行、全场景覆盖三大目标。 目录1、加入MindSpore社区2、安装前准备2.1、获取安装命令2.2、安装pip2.3、确认系统环境3、安装Mi…...

PRML笔记4-绪论中推断和决策小结

在推断阶段使用训练数据学习后验概率p(Ck∣x)p(\mathcal{C_k}|\boldsymbol{x})p(Ck​∣x)的模型;在决策阶段使用后验概率进行最优的分类;亦或是同时解决推断和决策问题,简单的学习一个函数f(x)f(\boldsymbol{x})f(x),将输入x\bold…...

DSPE-PEG-Streptavidin;Streptavidin-PEG-DSPE;磷脂聚乙二醇链霉亲和素,科研用试剂

DSPE-PEG-Streptavidin 中文名称:二硬脂酰基磷脂酰乙醇胺-聚乙二醇-链霉亲和素 中文别名:磷脂-聚乙二醇-链霉亲和素;链霉亲和素PEG磷脂 英文常用名:DSPE-PEG-Streptavidin;Streptavidin-PEG-DSPE 外观:粉…...

Java中的Stream

Stream流的特点 中间操作返回的是Stream类型,终结操作返回的是void 中间操作的这个Lazy指的是增加待处理操作,而不会真的处理(放队列里),集合中的数据并未实际改变,到终结操作的时候才会把这些放队列里的操…...

【数据库】关系数据理论

第六章关系数据理论 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r9ETJ75y-1677334548439)(imgs/image-20220508202554924.png)] 数据依赖 是一个关系内部属性与属性之间的一种约束关系 函数依赖多值依赖 函数依赖 [外链图片转存失败,源站可…...

新手入门:用快马生成第一个交易平台风格的前端页面

今天想和大家分享一个特别适合前端新手的练手项目——用InsCode(快马)平台快速搭建一个简易的交易平台前端页面。作为一个刚接触金融科技开发的小白,我发现这种模拟真实业务场景的项目特别能激发学习兴趣。 项目目标拆解 这个模拟交易账户页面需要实现几个核心功能模…...

射频工程师必备:如何用ADS仿真优化PA和LNA的噪声系数?

射频工程师必备:ADS仿真优化PA与LNA噪声系数的实战手册 在5G和物联网设备爆发式增长的今天,射频前端模块的性能直接决定了通信质量的上限。作为射频电路设计的核心环节,功率放大器(PA)和低噪声放大器(LNA)的噪声系数优化,往往是决…...

手把手教你用RK3576开发板驱动RC522读卡器:一个SPI实战项目的完整配置流程

手把手教你用RK3576开发板驱动RC522读卡器:一个SPI实战项目的完整配置流程 在嵌入式开发领域,能够独立完成一个从硬件连接到软件驱动的完整项目,是每个开发者成长的必经之路。RK3576作为一款性能强劲的开发板,搭配常见的RC522读卡…...

Unity 6升级后频繁闪退?别慌,这8个D3D11崩溃的修复方法亲测有效

Unity 6升级后D3D11崩溃全攻略:从快速修复到深度优化 刚升级到Unity 6的开发者们,是否正被突如其来的编辑器崩溃搞得焦头烂额?那些令人抓狂的"D3D11设备丢失"弹窗,不仅打断工作流,还可能让宝贵项目进度陷入停…...

图片去水印 API 接口实战:网站如何实现自动去水印(Python / PHP / C#)

在做网站或后台系统时,一个很常见但容易被忽视的问题是: 👉 用户上传的图片自带水印 👉 平台展示希望统一成干净版本 👉 还要支持批量、自动化处理 👉 最好能无缝接入现有系统 如果你正在找: …...

收藏!小白程序员必看:Agent和工作流是最佳拍档,教你如何协同它们(附案例)

文章探讨了AI智能体(Agent)和工作流工具的关系,指出它们并非竞争对手,而是最佳拍档。Agent擅长自主决策和动态规划,适用于探索性和不确定性任务;工作流则负责流程编排和确定性执行,适用于重复性…...

CoPaw个人助理深度体验:多通道对话+定时执行,解放双手的实用工具

CoPaw个人助理深度体验:多通道对话定时执行,解放双手的实用工具 1. CoPaw简介与核心功能 CoPaw是一款基于Qwen3-4B-Instruct-2507模型的个人助理型产品,由AgentScope团队开发。它最大的特点是能够部署在用户自己的环境中,实现数…...

Linux性能优化之上下文切换

写在前面 上下文切换因为会导致消耗大量的CPU资源,导致CPU升高,所以上下文切换也是最常见的性能杀手之一。本文就一起来看下这部分内容吧。 1:基础内容介绍 1.1:什么是上下文切换? CPU在执行的时候需要两部分的内容…...

Janus-Pro-7B效果展示:手写体/表格/多语言混合OCR识别准确率实测

Janus-Pro-7B效果展示:手写体/表格/多语言混合OCR识别准确率实测 1. 引言 你有没有遇到过这样的场景?翻出一张老照片,背面是长辈用钢笔写下的寄语,字迹有些潦草,想把它转成电子版保存,却一个字也认不出来…...

ESP32-S3驱动ILI9341屏幕避坑指南:从LVGL组件手动移植到流畅显示(ESP-IDF 5.4.1)

ESP32-S3驱动ILI9341屏幕避坑指南:从LVGL组件手动移植到流畅显示(ESP-IDF 5.4.1) 当你在ESP32-S3上尝试将LVGL移植到ILI9341屏幕时,可能会遇到各种奇怪的问题:内存溢出、屏幕模糊、驱动不匹配等。这些问题往往让开发者…...