文章目录
- 1.jdk spi 机制
- 2.dubbo spi机制
1.jdk spi 机制
SomeService:
package com.abc.service;
public interface SomeService {
void hello();
}
OneServiceImpl
public class OneServiceImpl implements SomeService {
public void hello() {
System.out.println("执行OneServiceImpl的hello()方法");
}
}
TwoServiceImpl
public class TwoServiceImpl implements SomeService {
public void hello() {
System.out.println("执行TwoServiceImpl的hello()方法");
}
}
SPITest
public class SPITest {
public static void main(String[] args) {
// load()中放的是业务接口,其就相当于要加载的配置文件名
ServiceLoader<SomeService> loader = ServiceLoader.load(SomeService.class);
Iterator<SomeService> it = loader.iterator();
while (it.hasNext()) {
SomeService service = it.next();
service.hello();
}
}
}
ServiceLoader.load():
迭代器方法:
jdk的spi的缺点为不可以是懒加载, 就是说必须全部加载然后for循环。
2.dubbo spi机制
key=value模式, 可以指定多个key
这里的目录结构为 3种
- META-INF/dubbo/internal
- META-INF/dubbo
- META-INF/services
Order
"alipay")(
public interface Order {
// 支付方式
String way();
}
AlipayOrder
public class AlipayOrder implements Order {
public String way() {
System.out.println("--- 使用支付宝支付 ---");
return "支付宝支付";
}
}
WechatOrder
public class WechatOrder implements Order {
public String way() {
System.out.println("--- 使用微信支付 ---");
return "微信支付";
}
}
OrderTest
public class OrderTest {
public void test01() {
// 获取到用于加载Order类型扩展类实例的extensionLoader实例
ExtensionLoader<Order> loader = ExtensionLoader.getExtensionLoader(Order.class);
Order alipay = loader.getExtension("alipay");
System.out.println(alipay.way());
Order wechat = loader.getExtension("wechat");
System.out.println(wechat.way());
}
public void test02() {
// 获取到用于加载Order类型扩展类实例的extensionLoader实例
ExtensionLoader<Order> loader = ExtensionLoader.getExtensionLoader(Order.class);
Order wechat2 = loader.getExtension("wechat2");
System.out.println(wechat2.way());
Order wechat = loader.getExtension("wechat");
System.out.println(wechat.way());
}
方法
public void test03() {
// 获取到用于加载Order类型扩展类实例的extensionLoader实例
ExtensionLoader<Order> loader = ExtensionLoader.getExtensionLoader(Order.class);
// 以下方式都会报错
// Order alipay = loader.getExtension(null);
// Order alipay = loader.getExtension("");
// 以下方式不会报错,其会加载SPI接口指定的默认名称的扩展类,
// 但SPI接口默认名称不是这样使用的
Order alipay = loader.getExtension("true");
System.out.println(alipay.way());
}
}
因为Order的spi注解上面默认的是alipay
所以如果是test03的话给定的是true的话则为alipayOrder的方法。
ExtensionLoader.getExtensionLoader():
先获取到实例, 然后getExtension()方法获取到接口的实现类。