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)] 数据依赖 是一个关系内部属性与属性之间的一种约束关系 函数依赖多值依赖 函数依赖 [外链图片转存失败,源站可…...

初阶C语言——结构体【详解】
文章目录1. 结构体的声明1.1 结构的基础知识1.2 结构的声明1.3 结构成员的类型1.4 结构体变量的定义和初始化2. 结构体成员的访问3. 结构体传参1. 结构体的声明 1.1 结构的基础知识 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 …...

盘点:9款身份和访问管理工具
身份和访问管理(IAM)长期以来一直是安全领导者职业生涯的关键“试炼场”,许多人在身份技术部署方面做出了事关成败的决定。 确保安全访问和身份管理是网络安全态势的两大基础 。同时,人员、应用程序和系统登录的方式以及它们彼此集…...

Linux下的进程地址空间
Linux下的进程地址空间程序地址空间回顾从代码结果推结论引入进程地址空间页表为什么要有进程地址空间重新理解进程地址空间程序地址空间回顾 我们在初学C/C的时候,我们会经常看见老师们画这样的内存布局图: 可是这真的是内存吗? 如果不是它…...

Web Spider Ast-Hook 浏览器内存漫游 - 数据检索
文章目录一、资源下载二、通过npm安装anyproxy模块三、anyproxy的介绍以及基本使用1. anyproxy的功能介绍2. anyproxy的基本使用四、给浏览器挂代理五、实操极验demo案例总结提示:以下是本篇文章正文内容,下面案例可供参考 一、资源下载 Github&#x…...

开源启智,筑梦未来!第四届OpenI/O启智开发者大会开幕
2023年2月24日,第四届OpenI/O启智开发者大会在深圳顺利开幕。本次活动由鹏城实验室、新一代人工智能产业技术创新战略联盟(AITISA)主办,OpenI启智社区、中关村视听产业技术创新联盟(AVSA)承办,华…...

CS144-Lab6
概述 在本周的实验中,你将在现有的NetworkInterface基础上实现一个IP路由器,从而结束本课程。路由器有几个网络接口,可以在其中任何一个接口上接收互联网数据报。路由器的工作是根据路由表转发它得到的数据报:一个规则列表&#…...

最好的个人品牌策略是什么样的
在这个自我营销的时代,个人品牌越来越受到人们的重视。您的个人品牌的成功与否取决于您在专业领域拥有的知识,以及拥有将这些知识传达给其他用户的能力。如果人们认为您没有能力并且无法有效地分享有用的知识,那么您就很难获得关注并实现长远…...

第四届国际步态识别竞赛HID2023已经启动,欢迎报名
欢迎参加第四届HID 2023竞赛,证明您的实力,推动步态识别研究发展!本次竞赛的亮点:总额人民币19,000元奖金;最新的SUSTech-Competition步态数据集;比上一届更充裕的准备时间;OpenGait开源程序帮您…...

「2」指针进阶——详解
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀 目录 🐰指向函数指针数组的指针(很少用,了解) 🐰回调函数&…...

计网笔记 网络层(端到端的服务)
第三章 网络层(端到端的服务) **TCP/IP体系中网络层向上只提供简单灵活的、无连接的、尽最大努力交付的数据报服务。**网路层不提供服务质量的承诺,不保证分组交付的时限,所传送的分组可能出错、丢失、重复和失序。进程之间通信的…...