apisdk-starter自动装配的思路与应用

apisdk-starter整体思路

首先定义开发者定义的开放接口声明为原始类,javassist生成的类是增强类。

  1. 使用springboot的EnableAutoConfiguration和Import触发Spring扫描组件扫描原始类,得到所有BeanDefinition
  2. 拓展FactoryBean,构造函数的参数为原始类的Class
  3. 遍历BeanDefinition,设置beanClass为拓展的FactoryBean的Class,构造参数是原始类的Class,这样FactoryBean会把原始类对象的生命周期交给spring管理,开发者可以通过@Resource完成依赖注入
  4. 在FactoryBean#getObject实例化原始类的代理对象时,使用javassist复制原始类,在内存中生成增强类,然后在方法参数上追加SdkContext参数声明,这样增强类就满足了apisdk的要求,通过apisdk生成增强类的代理对象,和原始类的代理对象形成映射关系。

有了原始类和增强类的映射关系后,接下来要解决运行时,如何查找增强类的代理对象,如何构建SdkContext请求上下文的问题。要解决这个问题,就要在原始类的代理对象着手。

  1. 抽取spring aop的源码,用aop的JdkDynamicAopProxy创建原始类的代理对象,即FactoryBean#getObject方法返回的对象,这样可以做到执行原始类的方法时,查找增强类的代理对象,发起Http请求,同时在这里做了失败重试的机制
  2. 拓展参数可变的前置通知,用于SdkContext参数的构建,本质是调用了RegionMock、SecretMock和TokenMock服务,然后把SdkContext参数追加到请求参数中

以上就是apisdk-starter的整体思路,其中抽取spring aop源码是为了脱离spring容器,apisdk-starter仍然可以运行。

apisdk-starter思路分解

我把整体思路中的前3点归结为Spriing拓展点,第4点是javassist字节码技术,后面两点是aop拓展。

首先我们先看下成品的apisdk-starter是如何使用的,接下来会按照思路分解进行技术分享。

apisdk-starter的应用

开放接口声明

在这里插入图片描述
可以看到,接口声明已经不再需要SdkContext参数声明。

接口调用

在这里插入图片描述
调用时不需要再关心如何调用RegionMock、SecretMock、TokenMock等服务,甚至开发者不需要知道有这些服务。