Dubbo SPI 原理¶
一、什么是 SPI¶
SPI(Service Provider Interface)是一种动态加载扩展点的机制。Java 自带 ServiceLoader,Dubbo 在此基础上做了增强。
二、Java 原生 SPI 的问题¶
- 会一次性实例化所有实现,不支持按需加载。
- 实现之间没有依赖注入 / 包装。
- 失败时难以定位是哪个实现出问题。
三、Dubbo SPI 做了什么¶
Dubbo 在 META-INF/dubbo/ 目录下配置扩展点:
内容:
netty=org.apache.dubbo.remoting.transport.netty.NettyTransporter
mina=org.apache.dubbo.remoting.transport.mina.MinaTransporter
用法:
ExtensionLoader<Transporter> loader =
ExtensionLoader.getExtensionLoader(Transporter.class);
Transporter netty = loader.getExtension("netty");
四、核心能力¶
1. 按需加载¶
按 key 加载具体实现,不一次性实例化所有。
2. IOC(依赖注入)¶
Dubbo SPI 支持 setter 注入:如果扩展实现依赖另一个扩展,Dubbo 会自动注入。
3. AOP(包装类)¶
Wrapper 类:
public class TransporterWrapper implements Transporter {
private final Transporter transporter;
public TransporterWrapper(Transporter t) { this.transporter = t; }
}
Dubbo 自动识别 Wrapper,在加载真实实现时包装一层。
4. Adaptive(自适应扩展)¶
@Adaptive 注解让方法调用时根据 URL 参数动态选择实现:
调用时 Dubbo 生成一个 Protocol$Adaptive,根据 url.getProtocol() 选择具体实现。
5. Activation(激活)¶
@Activate 按条件自动激活扩展,如过滤器。
五、Dubbo 启动时做了什么¶
- 扫描所有
META-INF/dubbo/下的配置文件。 - 把每个扩展点的 key → 实现类缓存到内存。
- 根据 URL 参数选择具体实现。
- 注入依赖、包装 AOP、生成 Adaptive。
高频追问
- Dubbo SPI vs Java SPI:按需加载、IOC、AOP、自适应。
@SPI("dubbo"):默认实现是 dubbo。- Dubbo 几乎所有核心组件(Protocol、Transport、Serialiation、Cluster、LoadBalance)都是 SPI 扩展。