关于 dubbo 的 SpiExtensionFactory 的一点说明
程序员文章站
2022-07-13 11:02:06
...
关于 dubbo 的 SpiExtensionFactory 的一点说明:
本篇文章不想比较 dubbo 的 spi 和 jdk spi 的异同,网上有太多文章写了这块,本篇文章主要想说 dubbo @Adaptive 注解的设计以及 SpiExtensionFactory 类.
我们先看下 SpiExtensionFactory 类:
public <T> T getExtension(Class<T> type, String name) {
// 必须是拓展点接口
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
// 获取该拓展点接口对应的 ExtensionLoader 对象
ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
// 如果该拓展点有其它的实现类,其它指的是既非 @Adaptive 标注也非该接口包装类
// 返回其 Adaptive 实现类
if (!loader.getSupportedExtensions().isEmpty()) {
return loader.getAdaptiveExtension();(1)
//return loader.getExtension(name);(2)
}
}
return null;
}
小伙伴们有疑问吗?为啥 dubbo 不采用 (2) 这种简单粗暴的做法,而是采用 (1) 这种了?
原因在于 @Adaptive. 如果按照(2) 的做法,那么 dubbo SPI 将不能通过参数控制调用那个实现类,同时关于其层层依赖注入是事先确定的,而采用(1) 这种实现方法,可以通过 URL 指定具体调用的实现类,同时在依赖输入的时候,是注入的 XXX$Adaptive 类,具体的注入会在指定完实际的实现类后进行注入,这样极大的增加了代码的灵活性和可扩展性.
本篇文章不想比较 dubbo 的 spi 和 jdk spi 的异同,网上有太多文章写了这块,本篇文章主要想说 dubbo @Adaptive 注解的设计以及 SpiExtensionFactory 类.
我们先看下 SpiExtensionFactory 类:
public <T> T getExtension(Class<T> type, String name) {
// 必须是拓展点接口
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
// 获取该拓展点接口对应的 ExtensionLoader 对象
ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
// 如果该拓展点有其它的实现类,其它指的是既非 @Adaptive 标注也非该接口包装类
// 返回其 Adaptive 实现类
if (!loader.getSupportedExtensions().isEmpty()) {
return loader.getAdaptiveExtension();(1)
//return loader.getExtension(name);(2)
}
}
return null;
}
小伙伴们有疑问吗?为啥 dubbo 不采用 (2) 这种简单粗暴的做法,而是采用 (1) 这种了?
原因在于 @Adaptive. 如果按照(2) 的做法,那么 dubbo SPI 将不能通过参数控制调用那个实现类,同时关于其层层依赖注入是事先确定的,而采用(1) 这种实现方法,可以通过 URL 指定具体调用的实现类,同时在依赖输入的时候,是注入的 XXX$Adaptive 类,具体的注入会在指定完实际的实现类后进行注入,这样极大的增加了代码的灵活性和可扩展性.
上一篇: dubbo http 协议分析