Dubbo SPI
SPI(Service Provider Interface)是 Dubbo 的核心扩展机制,允许通过配置文件动态替换实现类。SPI 详细介绍了 JDK SPI 和 Spring SPI 的机制。
核心注解
| 注解 | 说明 |
|---|---|
@SPI | 标记接口为可扩展接口 |
@Adaptive | 标记实现类为自适应扩展点 |
@SPI
标记接口为可扩展接口,并指定默认实现:
@SPI("dubbo")
public interface RpcClient {
void send(Object message);
}"dubbo" 表示默认使用 Dubbo 协议的实现。
@Adaptive
标记实现类为自适应扩展点,Dubbo 会根据运行时参数选择具体实现:
@Adaptive
public class DubboRpcClient implements RpcClient {
@Override
public void send(Object message) {
// Dubbo 协议实现
}
}SPI 配置文件
SPI 配置文件放置在 META-INF/dubbo/ 目录下,文件名为接口全限定名,内容为 key=value 格式:
# META-INF/dubbo/com.example.RpcClient
dubbo=com.example.DubboRpcClient
http=com.example.HttpRpcClient扩展加载流程
@Activate 自动激活
@Activate 让扩展按条件自动生效,无需手动指定——常见于过滤器、拦截器这类"默认都要装上"的扩展。条件由 value(URL 参数名)和 group(consumer/provider 侧)控制:
@Activate(group = "provider", order = 100) // provider 侧自动激活,order 控制执行顺序
public class AccessLogFilter implements Filter {
// 所有 provider 都会自动套上此过滤器
}
@Activate(value = "cache") // 仅 URL 含 cache 参数时激活
public class CacheFilter implements Filter { }与 @SPI(声明扩展点)、@Adaptive(按参数动态选择)配合:@Activate 解决"一组扩展默认全启用"的场景,如 Dubbo 内置的多个 Filter 按 order 依次执行。
应用场景
- 协议切换:根据配置在 Dubbo、HTTP、gRPC 等协议间切换
- 序列化方式:动态选择 JSON、Protobuf、Hessian 等序列化方案
- 负载均衡策略:运行时切换 Random、RoundRobin 等策略
- 过滤器链:
@Activate自动装配日志、限流、鉴权等 Filter
常见问题
| 问题 | 解决方案 |
|---|---|
| 扩展点加载失败 | 确认配置文件路径为 META-INF/dubbo/ 且文件名为接口全限定名;检查 key=value 格式;确认实现类有无参构造函数 |
@Adaptive 不生效 | 确认注解标记在实现类上而非接口上;检查 URL 参数中是否包含对应的 key |