Seata 如何使用 SPI
Seata 是一个分布式事务的框架,具体的使用这里不再赘述,有时间可以出专门写它的文章。本节主要关注 Seata 是如何利用 SPI 的方式进行框架能力扩展的。
在 Seata 框架中使用 EnhancedServiceLoader 实现服务载入,通过名称我们可以知道他是一种增强型的 ServiceLoader 。那么相对于 JDK 自身的 ServiceLoader ,他到底强在哪里呢?
由下图可知, EnhancedServiceLoader 不仅支持 Java 原生的服务发现目录,同样支持自己自定义的 META-INF/seata/ 目录。
另外在具体接口实现类上都有 @LoadLevel 的注解,如果其中有多个配置中心实现类都被加载,那么可以根据对应注解上的属性 order 进行排序。将实际优先级最大的类进行加载。
我们都知道注册中心是微服务体系中的必不可少的基础组件,它记录了服务提供者的地址信息。那么在 Seata 中, Seata 的客户端如事务管理器 TM 、资源管理器 RM 需要与事务协调者 TC 进行通信,那么就需要通过注册中心来获取服务端的地址信息。 Seata 注册中心支持多个第三方注册中心,如 Consul 、 Apollo 、 Etcd3 等。我们来看下 Seata 是怎么使用 SPI 机制来实现对于多个注册中心扩展支持的。
首先定义一个 ConfigurationProvider 的接口,你看是不是嗅到了熟悉的味道,只要使用 SPI 那么就需要首先把规矩给小弟们定好。
接着在对应的包 META-INF/services/ 中定义具体实现类,如此处的 Consul 配置中心中定义了 ConsulConfigurationProvider 。
我们可以看到 ConsulConfigurationProvider 实现了 ConfigurationProvider 的接口。