掘金 后端 ( ) • 2024-04-02 10:44

一、背景

在之前的分享中,我们的专题内容更新到了第4节,前几节内容如下:

跟我一起学开源设计第1节:封装埋点GrowingIO Spring Boot Starter组件

跟我一起学开源设计第2节:SpringBoot Starter组件中的4项高级设计

跟我一起学开源设计第3节: 开源的服务端用户埋点SDK源码设计与实现分析

跟我一起学开源设计第4节: 支付SDK学习前置:申请个人签约支付平台

本文是开源设计系列分享的第5篇文章,上篇文章我们申请了一个支持个人签约的蓝兔支付商户,如果自己有备案的域名申请还是非常容易的,10-20分钟就可以申请下来一个属于自己的商户号,开开心心玩微信支付,那么既然已经有了微信商户号,我们在后续的过程中通过学习开源项目的设计,自己封装出一个蓝兔支付的SDK,然后完成业务的支付对接。

本文开始介绍开源项目:基于微信API封装的开源微信工具包wxjava。

个人是非常推荐大家来学习这个项目,即使自己不开通或者没条件开通微信平台的相关API,也是非常值得我们学习,它里面的某些设计都是可以复用的,同时里面的很多地方都是成套路式的开发和设计,熟悉了以后,是完全可以根据他的思想,设计任何一套SDK的管理能力的组件的。本小节简单介绍下该项目中的starter的设计。

本文计划采用一种自顶向下的方式,通过从最顶层的Starter入手,来进入SDK的设计和学习,掌握这个方法,可以比较快速的来属性一些开源项目,以及当想设计一个SDK,自己无从下手时,可以反推出来SDK需要提供哪些功能,本文主要介绍下wxjava中的starter的设计。

二、wxjava能给我们带来什么

可能很多人会受限于没有微信平台相关资质、账号、条件等而放弃了学习与了解,从我个人的角度,我觉得是没影响的顶多是发送请求的报错而已,不影响我们调试和属性框架的流程。

wxjava是一个微信开发 Java SDK,它支持微信支付、开放平台、公众号、企业号/企业微信、小程序等的后端开发。项目地址:https://gitee.com/binary/weixin-java-tools

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

  • 统一抽象多种HTTP请求框架与泛型的设计与实现
  • 请求三方必填参数@Require注解校验设计与实现
  • 错误重试的设计与实现
  • 请求参数的签名的设计与实现
  • 基于accessToken模式的SDK设计思路与高可用的设计
  • 基于内存和Redis的消息重复检查器
  • 微信平台对外提供的业务能力

我相信,当你掌握了这些设计思想和能力之后,你的技术水平与个人设计能力也会提升,也会逐渐的设计出符合需求的SDK工具包。

在wxjava开源项目中,针对微信平台下的生态,它为每个生态都封装了一个对应的工程,比如:

  1. 微信小程序:weixin-java-miniapp
  2. 微信支付:weixin-java-pay
  3. 微信开放平台:weixin-java-open
  4. 公众号(包括订阅号和服务号):weixin-java-mp
  5. 企业号/企业微信:weixin-java-cp

那么,以后自己相对接微信生态下的某一个服务时,引入对应的工程依赖即可。

对于程序员来说,学习wxjava项目具有以下价值:

  1. 提高开发效率:wxjava提供了丰富的功能封装和示例代码,帮助开发者快速实现微信平台的各种功能,大大提高了开发效率。
  2. 深入理解微信平台:通过学习wxjava项目,开发者可以深入了解微信平台的工作机制、接口调用方式等,提升自己对微信开发的理解。
  3. 增加竞争力:微信平台是众多企业和个人开发者都关注的领域,掌握wxjava项目可以让你在微信开发领域具备更强的竞争力。
  4. 助于项目开发:很多企业和个人项目都需要与微信平台进行交互,学习wxjava项目可以为你的项目开发提供参考和支持。

三、学习设计前思考几个问题

正如之前的几篇文章所说的,在行业的有些厉害的技术老师推荐的学习的方法其中一个是带着问题和目标去学习,这里我们也为自己准备几个问题,比如:

1、SDK封装Open API,通常需要考虑哪些点

2、SDK内部如何构造请求参数和发送请求的

3、SDK对于响应的解析与错误的处理大概是什么样的

4、SDK会用哪些设计模式解决问题

下篇文章我们解决这几个问题,如果自己能够在接下来的的旅途中,明白这几个问题是如何解决和设计的,我相信自己开发一个SDK应该已经具备了一定的基础了。

下面我分享一个关于SDK设计的固定套路,在后续的文章中,我们来解答这些内容。

四、wxjava中某个模块的处理

这里以wxjava中微信公众号工程的设计和对接进行处理。微信公众号的项目工程是weixin-java-mp。

你会不会想问:我想了解下,这个开源项目了解的话从哪里入手。

针对这个问题,我们要养成习惯去看他的starter或者工程中的测试例子,找到程序的Demo,通过Demo找到程序的入口,从而对程序进行跟踪和处理。

对于项目源码的构建和导入,这里暂时先不分享了,大家需要如下地址下载到源码,然后导入到IDEA开发工具中,编译构建即可。

https://gitee.com/binary/weixin-java-tools

导入后,截图如下所示:

然后我们找到wx-java-mp-spring-boot-starter这个代码工程,使用的方式可以参考:https://gitee.com/binary/weixin-java-tools/tree/develop/spring-boot-starters/wx-java-mp-spring-boot-starter

4.1、wxjava公众号模块给使用者提供的入口

我们可以看到在wxjava的工程下提供了一个wx-java-mp-spring-boot-starter的公众号的starter的工程,通过我们第1节到第3节的学习,相信大家具备了阅读一个Starter组件的能力,以及自定义一个starter组件的能力,那么针对这个starter,我们能够发现几个核心内容:

  1. XXXProperties类:提供了该starter对使用者开放的属性配置类。
  2. XXXService:提供了对使用者开放的服务访问的类,也是算是门面的一个体现。
  3. WxMpConfigStorage:提供了相关配置数据的存储策略,内存还是Redis。

也就是说,当我们使用的时候,先构造微信公众号的相关参数,同时把配置信息传递给微信公众号操作Service的业务入口类。大家可以自行阅读这个starter组件,带着我们一开始的提出的问题1:【给使用者提供若干配置入口】来阅读,最后就会总结出核心就是上面这几个类。

入口的Properties和Configuration的配置代码如下:

@Data
@ConfigurationProperties(PREFIX)
public class WxMpProperties {
  public static final String PREFIX = "wx.mp";

  /**
   * 设置微信公众号的appid.
   */
  private String appId;

  /**
   * 设置微信公众号的app secret.
   */
  private String secret;

  /**
   * 设置微信公众号的token.
   */
  private String token;

  /**
   * 设置微信公众号的EncodingAESKey.
   */
  private String aesKey;

  /**
   * 自定义host配置
   */
  private HostConfig hosts;

  /**
   * 存储策略
   */
  private final ConfigStorage configStorage = new ConfigStorage();

  @Data
  public static class ConfigStorage implements Serializable {
    private static final long serialVersionUID = 4815731027000065434L;
    /**
     * 存储类型.
     */
    private StorageType type = Memory;
    /**
     * 指定key前缀.
     */
    private String keyPrefix = "wx";
}

自动加载类的代码如下

@Configuration
@EnableConfigurationProperties(WxMpProperties.class)
@Import({ WxMpStorageAutoConfiguration.class, WxMpServiceAutoConfiguration.class })
public class WxMpAutoConfiguration {
}

4.2、WxMpService类的加载

在自动装配类中,通过@Import({ WxMpStorageAutoConfiguration.class, WxMpServiceAutoConfiguration.class })代码,加载了2个自动装配类,我们看到该项目中针对不同的HTTP请求封装了具体的业务Service实现:

@Bean
  @ConditionalOnMissingBean
  public WxMpService wxMpService(WxMpConfigStorage configStorage, WxMpProperties wxMpProperties) {
    HttpClientType httpClientType = wxMpProperties.getConfigStorage().getHttpClientType();
    WxMpService wxMpService;
    switch (httpClientType) {
      case OkHttp:
        wxMpService = newWxMpServiceOkHttpImpl();
        break;
      case JoddHttp:
        wxMpService = newWxMpServiceJoddHttpImpl();
        break;
      case HttpClient:
        wxMpService = newWxMpServiceHttpClientImpl();
        break;
      default:
        wxMpService = newWxMpServiceImpl();
        break;
    }

这个设计也是值得我们学习的。感兴趣的小伙伴可以看下代码,这里我们能学习到一种抽象HTTP模型的设计,如何用一个接口实现多种HTTP请求框架与业务代码的集成。

4.3、一种新的SPI声明方式

在该项目的starter中,提供了一个org.springframework.boot.autoconfigure.AutoConfiguration.imports的文件,该文件也是一个Spring Boot Starter提供的玩法,从Spring Boot 2.7开始,新的SPI文件定义的方式,也是值得我们学习的。

从wxjava项目提供的多个starter工程中,可以看到一个标准的Spring Boot Starter需要包括一个XxxxProperties的属性配置类、一个XxxxxAutoConfiguration的自动装配的配置类,一个spring.factories的自动装配的文件。

五、总结

本文总结了开源项目wxjava的其中一个starter,希望大家通过前面几节的内容能够看到该项目的几个starter,也可以访问该项目的Demo工程:

https://gitee.com/binary/weixin-java-mp-demo-springboot

https://gitee.com/binary/projects

可以提前熟悉下starter,下节我们分析核心源码设计思路

六、练习

1、尝试下载wxjava的工程源码,在IDEA中导入下,搭建下源码环境

2、熟悉starter工程中的样例,与Demo工程中的使用方法,对其API的封装和使用熟悉下套路