![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSP9EVT1EFRNZHdywEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcuIzMzMTMzETM3ADOwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
建立API子產品-dubbo-spi-demo-api
- api添加依賴
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.5</version>
</dependency>
</dependencies>
- 建立Service-添加spi注解
@SPI
public interface HelloService {
String sayHello();
}
- 建立實作-依賴上面的子產品
Dubbo-spi-demo與Adaptive使用
public class DogHelloServiceImpl implements HelloService {
@Override
public String sayHello() {
return "hello dog";
}
}
public class HumanHelloServiceImpl implements HelloService {
@Override
public String sayHello() {
return "hello Human";
}
}
- 在resources目錄下建立META-INF/dubbo目錄 檔案名就是接口名-内容key=value
Dubbo-spi-demo與Adaptive使用
dog=com.liu.service.impl.DogHelloServiceImpl
human=com.liu.service.impl.HumanHelloServiceImpl
- 測試
ExtensionLoader<HelloService> extensionLoader = ExtensionLoader.getExtensionLoader(HelloService.class);
Set<String> supportedExtensions = extensionLoader.getSupportedExtensions();
supportedExtensions.forEach(s->{
System.out.println(extensionLoader.getExtension(s).sayHello());
});
hello dog
hello Human
- 添加spi預設-在接口上
@SPI("dog")
public interface HelloService {
String sayHello();
}
- 測試修改
public static void main(String[] args) {
ExtensionLoader<HelloService> extensionLoader = ExtensionLoader.getExtensionLoader(HelloService.class);
Set<String> supportedExtensions = extensionLoader.getSupportedExtensions();
supportedExtensions.forEach(s->{
System.out.println(extensionLoader.getExtension(s).sayHello());
});
System.out.println("===============");
HelloService defaultExtension = extensionLoader.getDefaultExtension();
System.out.println(defaultExtension.sayHello());
}
}
hello dog
hello Human
===============
hello dog
getDefaultExtension可以擷取預設配置的是哪個接口實作
-
JDK 标準的 SPI 會一次性執行個體化擴充點所有實作,如果有擴充實作初始化很耗時,但如果沒用上也加
載,會很浪費資源
- 如果有擴充點加載失敗,則所有擴充點無法使用
Adaptive
@SPI("dog")
public interface HelloService {
String sayHello();
@Adaptive
String sayHello(URL url);
}
public class DogHelloServiceImpl implements HelloService {
@Override
public String sayHello() {
return "hello dog";
}
@Override
public String sayHello(URL url) {
return "hello dog : "+url;
}
}
public class HumanHelloServiceImpl implements HelloService {
@Override
public String sayHello() {
return "hello Human";
}
@Override
public String sayHello(URL url) {
return "hello Human "+url;
}
}
public class AdaptiveMain {
public static void main(String[] args) {
/**
* 這裡注意?後面
* hello.service=HelloService
* =後面就是在配置檔案中的key
*/
URL url = URL.valueOf("test://localhost/hello?hello.service=human");
ExtensionLoader<HelloService> extensionLoader = ExtensionLoader.getExtensionLoader(HelloService.class);
HelloService helloService = extensionLoader.getAdaptiveExtension();
System.out.println(helloService.sayHello(url));
}
}
hello Human test://localhost/hello?hello.service=human
如果不寫就調用@SPI注解配置的,
public class AdaptiveMain {
public static void main(String[] args) {
/**
* 這裡注意?後面
* hello.service=HelloService
* =後面就是在配置檔案中的key
* ?hello.service=human
*/
URL url = URL.valueOf("test://localhost/hello");
ExtensionLoader<HelloService> extensionLoader = ExtensionLoader.getExtensionLoader(HelloService.class);
HelloService helloService = extensionLoader.getAdaptiveExtension();
System.out.println(helloService.sayHello(url));
}
}
hello dog : test://localhost/hello