SPI 服务提供者接口
ServiceLoader
SPI 全名 Service Provider Interface ,是java提供的 一个 服务接口拓展机制。使用SPI 可以轻松的修改接口的实现方式。
例子代码:
创建一个接口:
1 2 3 4 5 6 7 8 9 10 11 12 | /** * 描述 * * @Author ZHANGYUKUN * @Date 2022/6/27 */ public interface MyInterface { String doSome(); } |
创建2个实现类:
1 2 3 4 5 6 7 8 9 10 11 12 | /** * 描述 * * @Author ZHANGYUKUN * @Date 2022/6/27 */ public class Impl1 implements MyInterface { @Override public String doSome() { return "Impl1" ; } } |
1 2 3 4 5 6 7 8 9 10 11 12 | /** * 描述 * * @Author ZHANGYUKUN * @Date 2022/6/27 */ public class Impl2 implements MyInterface { @Override public String doSome() { return "Impl2" ; } } |
然后再classpath下面创建 META-INF/services 两个目录
在 META-INF/services 里面建一个文件名为接口全称的文件:com.lomi.spi.MyInterface
文件里面写着接口的实现类的全类名:com.lomi.spi.Impl2
然后我们通过 ServiceLoader 获取接口实现,可以拿到我们指定接口实现类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package com.lomi.spi; import java.util.Iterator; import java.util.ServiceLoader; /** * 描述 * * @Author ZHANGYUKUN * @Date 2022/6/27 */ public class Main { public static void main(String[] args) { ServiceLoader<MyInterface> loadedDrivers = ServiceLoader.load(MyInterface. class ); Iterator<MyInterface> driversIterator = loadedDrivers.iterator(); while (driversIterator.hasNext()) { MyInterface myInterface = driversIterator.next(); System.out.println( myInterface.getClass() ); } System.out.println( "over................." ); } } |
很多jar都是通过这种方式来切换接口实现类的,比如 SLF4j 导入对应的装换包,就会换成对应的实现, 原理就是 对应的实现包里面 指定了实现类
dubbo 的 SPI 也是类似的机制,但是支持 实现key名字=实现类全名格式,,并且可以在接口上指定默认使用那个key对应的实现,获取接口实现类是通过 ExtensionLoader 来获取的
获取指定 key 的实现类,和查看有那些实现
public static void main(String[] args) {
ExtensionLoader<Filter> extensionLoader = ExtensionLoader.getExtensionLoader(Filter.class);
//获取指定实现
Filter filter = extensionLoader.getExtension("dubboExceptionFilter");
System.out.println(filter.getClass());
//打印有那些实现
extensionLoader.getSupportedExtensions().forEach((itemKey) -> {
System.out.println(itemKey);
});
}
如果要在接口上指定默认实现可以使用直接 @SPI(“默认实现的key”)
能耍的时候就一定要耍,不能耍的时候一定要学。
--天道酬勤,贵在坚持posted on 2022-06-28 00:07 zhangyukun 阅读(142) 评论(0) 编辑 收藏 举报
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术