掘金 后端 ( ) • 2024-04-14 11:04

一、背景

1.1、简介

在之前分享的第5节中,我们简单介绍和分享了开源项目wxjava工具包的Spring Boot Starter的设计,可以看到在Starter的设计中,非常的轻量,没有过多的类,如果当前正在看文章的你,空闲时间有完成第5节的练习,可以发现或者感觉到wxjava工具包中的Starter都非常的相似,大体思路也都是一样的,既然如此我们可以总结出该项目的Starter的套路:

请牢记住这个套路,如果自己理解了这个套路,那么在后续的自定义SDK中,自己也会非常清楚,明白嘞这几步,日后我们通过一个Starter的设计就能推到和自顶向下式的设计出一个SDK。

1.2、分享wxjava的原因

通过了解他的设计思路,可以让自己掌握且具备设计一个对接API类型的SDK的能力,该SDK通过抽象设计与引入泛型统一了多种HTTP请求框架,实现了参数校验、错误重试与签名,展现了成熟的accessToken设计思路,是API对接设计的佳作。

优秀的设计的内容包括:

统一抽象多种HTTP请求框架与泛型的设计与实现

请求三方必填参数@Require注解校验设计与实现

错误重试的设计与实现

请求参数的签名的设计与实现

基于accessToken模式的SDK设计思路与高可用的设计

基于内存和Redis的消息重复检查器

1.3、学习wxjava项目的价值

提高开发效率:wxjava提供了丰富的功能封装和示例代码,帮助开发者快速实现微信平台的各种功能,大大提高了开发效率。

深入理解微信平台:通过学习wxjava项目,开发者可以深入了解微信平台的工作机制、接口调用方式等,提升自己对微信开发的理解。

增加竞争力:微信平台是众多企业和个人开发者都关注的领域,掌握wxjava项目可以让你在微信开发领域具备更强的竞争力。

助于项目开发:很多企业和个人项目都需要与微信平台进行交互,学习wxjava项目可以为你的项目开发提供参考和支持。

二、正文开始

现在开始跟我一起学习wxjava的核心流程,记得上一篇文章中,我画如下这样的一个图,这个图也是本文大家在跟我学习的过程中需要关注的几个点:

对于第1点,我们已经清楚了,wxjava这个项目抽象了一个Config配置对象,同时可能会提供基于内存、基于Redis的配置数据的存储。

对于第2点,wxjava教大家可以设计一个Properties的类,来让使用者提供应用的ID与秘钥信息等。

接下来我们我们便从核心的Service类来入手,进入开源项目wxjava的核心流程,我们先来关注下weixin-java-mp这个工程的结构,对于一个SDK的设计,核心就是:请求响应参数定义、配置定义与存储、业务请求处理、URL的维护和处理。

接下来,我们找到WxMpUserTagServiceImplTest这个单元测试类来进行流程跟踪。

2.1、以一个用户标签的业务为入口

1、首先我们找到wxjava工程中的这个类:WxMpUserTagServiceImplTest,这个类是微信公众平台项目下的一个关于用户标签的类,在测试标签的创建方法中个,我们看到如下代码:

在该代码中表达的就是一个创建标签的过程,那我们就以这个为入口,进行流程的梳理与学习。首先我们看到wxService就是我们在Starter中初始化的微信公众平台的WxMpService类,这个类就是我们的核心业务,同时该类负责两个作用:

  1. 提供对外访问API服务能力的接口
  2. 自身提供核心通用业务的方法,比如HTTP请求、解析等。

2.2、标签创建业务方法的封装实现

该流程的核心代码如下所示,不要小看他是一个非常简单的方法,他教会我们的设计也是不错的,先自己看1分钟:

这段方法教会了我们参数的定义、响应的解析。也就是说我们在SDK中封装API接口的时候,可以定义参数来接收具象化API接口文档中的参数,在定义一个实体类来将返回结果封装一个Java对象,对使用者来说只是调用一个方法,不用感知到具体的请求流程,同时wxMpServcie封装了一个通用的POST方法,第一个参数是URL,第二个是请求的字符串参数。在wxjava项目中,每个子工程都定义了请求和响应的实体,有些简单的API接口没有单独用一个类分装,参数多的接口都封装了对应的request和result模型。

比如当前的公众号模块:

比如当前的微信小程序的模块:

2.3、wxMpService中的Post方法实现

1、我们看到Post方法是多个重载方法,第一层的Post方法负责根据当前的Config存储对象生成URL,同时传递请求的Post的数据:

2、单击post方法,进入到第二层的Post处理,可以看到这里面创建了一个HTTP请求的执行器:

3、在单击execute方法,可以看到这个里面除了正常的请求,也会进行请求的最大次数重试和错误的处理。

4、在上面的三个步骤中,我们可以发现它为我们自动做了三件事情,也教会了我们SDK中需要考虑的内容:

  1. 取出存储配置,构造URL
  2. 定义HTTP请求处理器
  3. 请求出现错误进行重试

这三点也是我们值得学习的,当我们设计一个SDK的时候,需要考虑下请求接口的API的URL如何维护、如何兼容多种HTTP请求框架,请求出现错误如何处理。

先来看下如何取出存储配置,可以看到他用了一个Map存储我们在初始化的时候指定的config对象,同时如果在初始化的时候,配置了多个对象,我们通过Holder来取出来当前环境用的是哪个配置信息。

再来看下如何维护和取出URL信息,在微信公众号的模块中,是通过枚举类的方式来维护API地址的:

再来看看他是如何创建HTTP请求处理执行器的:

可以看到这是一个非常典型的策略模式和模板模式的处理,理解这个设计在我们后续的SDK开发和设计中,也是比较重要的。

这里我们可以学习到:抽象的HTTP模型设计,泛型方式对接第三方HTTP框架

在使用HTTP框架的时候,我们经常的动作就是:创建第三方HTTP请求对象、封装参数请求数据、解析响应数据。在wxjava中,结合以上步骤,自己在仔细的看看源码,可以发现它为我们设计了3套抽象设计:

RequestHttp<H,P>

RequestExecutor<T,E>

ResponseHandler

2.4、核心的executeInternal内部执行器实现

这个方法是整个SDK中最核心的一个部分,我们可以看到它先请求了accessToken方法,获取到了token,并拼接在了URL的后面作为参数传递,然后调用具体的请求执行器的执行方法获得一个请求,返回结果T,T是通过泛型来指定的,同时在错误中进行了token过期的处理。

再来看下如何获取的accessToken的,进入到token获取的方法,代码截图如下:

可以非常清晰的看到,他会先判断内存中的token是否过期,没过期直接返回,过期了就获得一把锁,然后发送获取Token的HTTP请求,从而生成新的Token数据。

在这段方法中,他教会了我们:

  1. 基于accessToken模式的Open API接口如何封装
  2. Token过期了如何处理
  3. 如何用一套请求处理器并结合泛型来支持不同URL的请求和响应数据

2.5、通用的请求处理器的设计与实现

经过刚才的一系列的分析,我们还剩最后一块的分享,就是到底如何发送请求的,到现在也没有看到一个用到了底层HTTP请求的方法,都是封装的方法,接下来我们看下这个,在刚才的请求方法中,用到了executor.execute方法,这个就是请求处理器的执行方法,根据签名几部的分析,可以知道,他这个做了多种请求执行器的实现,这里我们看下针对OKhttp请求处理器的实现代码:

可以非常清晰的看到,在这个HTTP请求模型下,每个具体的HTTP请求实现只需要关注自己的HTTP请求API逻辑即可,同时也基于类上的泛型实现了不同类库下面的HTTP请求模型的对接,也值得我们学习

至此,我们今天学习了开源项目wxjava的核心处理流程与关键的几个源码设计。

三、总结

3.1、设计模式

在wxjava中我们能够学习到的几个设计模型和原则如下:

单例设计模式:

基于静态内部类的WxMessageInMemoryDuplicateCheckerSingleton、

模板方法+策略设计模式

在RequestExecutor、SimplePostRequestExecutor、OkHttpSimplePostRequestExecutor的类层次设计上是一个非常典型的模板方法设计模式

依赖倒置原则

这个原则要求我们要依赖于抽象,不要依赖于具体。在这段代码中,SimplePostRequestExecutor 类依赖于一个抽象类型 RequestHttp<H, P>,而不是具体的实现。这有助于减少代码之间的耦合,使得 SimplePostRequestExecutor 可以与不同的 RequestHttp 实现一起工作。

开闭原则

wxjava对于扩展新功能保持开放,而对于修改现有功能则保持封闭。这意味着当微信平台推出新的功能或API时,开发者可以通过添加新的类或方法来进行扩展,而不需要修改现有的代码。

3.2、后续扩展

相信大家,经过这几个步骤的代码追踪,应该知道了我们文章中最开始分享的几个点,大家可以反复琢磨和思考,这几个点在未来非常有效的会帮助我们来设计自己的SDK,在设计这种基于Open API类型的SDK的时候,可以先按照固定的套路和方式,先设计出来Starter组件,然后缺少什么就创建什么,从顶向下的方式来驱动SDK的设计和编写。

我们要理解Starter的场景开发套路与今天学习到的这个SDK开发的套路。

后续文章我会分享基于这个项目的设计和思想,来封装蓝兔支付平台的SDK的开源项目,从而将自己的学习落地到实践中,目前源码我已放到Github中,Github地址为:

https://github.com/wuchubuzai2018/lantu-pay-sdk

感兴趣的小伙伴可以提前了解和使用下,再结合我们之前申请的蓝兔平台的商户号进行测试验证。感兴趣的小伙伴可以找我参与开源贡献,一起建设哦。

四、练习

1、根据我的思路和过程,尝试阅读和分析其他某个微信工程模块的流程

2、使用draw.io或processon工具,画一画当前的流程图或者时序图,看看是否自己理解了设计和思想

对本文感兴趣的,可以收藏、关注、分享、评论哦。