柚子快報(bào)邀請(qǐng)碼778899分享:Dubbo SPI機(jī)制使用
柚子快報(bào)邀請(qǐng)碼778899分享:Dubbo SPI機(jī)制使用
Java SPI機(jī)制博客傳送門:https://blog.csdn.net/qq_42402854/article/details/125705159 注意:JDK SPI會(huì)一次性實(shí)例化擴(kuò)展點(diǎn)的所有實(shí)現(xiàn)。
Dubbo沒有使用JDK的SPI機(jī)制,而是自己實(shí)現(xiàn)的一套SPI機(jī)制。在Dubbo的源碼中,很多地方會(huì)存在下面這樣的三種代碼:
//獲取自適應(yīng)擴(kuò)展點(diǎn)
ExtensionLoader.getExtensionLoader(xxx.class).getAdaptiveExtension();
//獲取指定名稱的擴(kuò)展點(diǎn)
ExtensionLoader.getExtensionLoader(xxx.class).getExtension(name);
//激活擴(kuò)展點(diǎn)
ExtensionLoader.getExtensionLoader(xxx.class).getActivateExtension(url, key);
在Dubbo中,SPI貫穿整個(gè)Dubbo的核心,所以理解Dubbo中的SPI對(duì)于理解Dubbo的原理有著至關(guān)重要的作用。
在Java中,通過 java.util.ServiceLoader 來發(fā)現(xiàn)動(dòng)態(tài)加載具體的實(shí)現(xiàn)類到JVM中。在Spring中,SpringFactoriesLoader這個(gè)類,它也是一種SPI機(jī)制。在Dubbo中,ExtensionLoader這個(gè)類,它也是一種SPI機(jī)制。
一、Dubbo SPI機(jī)制使用
1、Dubbo的 SPI機(jī)制
Dubbo的 SPI機(jī)制:來自《Apache Dubbo與實(shí)戰(zhàn)》一書中截圖。
1.1 擴(kuò)展點(diǎn)注解
1.1.1 @SPI注解
@SPI注解可以使用在類,接口和枚舉上。
主要作用就是標(biāo)記這個(gè)接口是一個(gè) Dubbo SPI接口,即一個(gè)擴(kuò)展點(diǎn)。 value,表示可以設(shè)置默認(rèn)的實(shí)現(xiàn)類
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SPI {
/**
* default extension name
*/
String value() default "";
}
1.1.2 @Adaptive注解
@Adaptive注解 可以標(biāo)記在類、接口、枚舉類和方法上。
自適應(yīng)擴(kuò)展點(diǎn)的知識(shí),表示在運(yùn)行時(shí)使用那個(gè)實(shí)現(xiàn)類。 當(dāng)該注解使用在類上時(shí),只能有一個(gè)實(shí)現(xiàn)類上可以加 @Adaptive注解,如果多個(gè)實(shí)現(xiàn)類都有該注解會(huì)拋出異常。
包裝類等其他的自行了解。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Adaptive {
String[] value() default {};
}
1.1.3 @Acticate注解
@Acticate注解 可以標(biāo)記在類、接口、枚舉類和方法上。
默認(rèn)自動(dòng)激活,主要使用在多個(gè)擴(kuò)展點(diǎn)實(shí)現(xiàn)、還可以根據(jù)不同條件被激活的場(chǎng)景中。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Activate {
String[] group() default {};
String[] value() default {};
String[] before() default {};
String[] after() default {};
int order() default 0;
}
2、獲取Protocol擴(kuò)展點(diǎn)
public static void main(String[] args) {
ExtensionLoader
Protocol dubbo = extensionLoader.getExtension("dubbo");
System.out.println("dubbo 指定名稱的擴(kuò)展點(diǎn):" + dubbo);
System.out.println("dubbo 自適應(yīng)擴(kuò)展點(diǎn):" + extensionLoader.getAdaptiveExtension());
System.out.println("dubbo 默認(rèn)擴(kuò)展點(diǎn)協(xié)議:" + extensionLoader.getDefaultExtension());
System.out.println("dubbo 獲取所有擴(kuò)展點(diǎn)協(xié)議:" + extensionLoader.getSupportedExtensions());
}
Protocol接口源碼如下:
二、自定義擴(kuò)展點(diǎn)
這里寫個(gè) demo 感受一下 dubbo的SPI機(jī)制。
1、定義擴(kuò)展點(diǎn)和實(shí)現(xiàn)類
1.1 擴(kuò)展點(diǎn)
@SPI注解:value,表示設(shè)置默認(rèn)的實(shí)現(xiàn)類
@SPI("MyLog")
public interface MyLog {
void debug();
}
1.2 實(shí)現(xiàn)類
這里定義三個(gè)實(shí)現(xiàn)類。
@Activate
public class MyLog4j implements MyLog{
@Override
public void debug() {
System.out.println("==========dubbo MyLog4j");
}
}
@Activate
public class MyLogback implements MyLog{
@Override
public void debug() {
System.out.println("==========dubbo MyLogback");
}
}
@Adaptive
//@Activate
public class MyAdaptiveLog implements MyLog{
@Override
public void debug() {
System.out.println("==========dubbo MyAdaptiveLog");
}
}
2、創(chuàng)建配置文件
在項(xiàng)目resources目錄下新建一個(gè) META-INF/dubbo/文件夾。
在 META-INF/dubbo/目錄下,創(chuàng)建一個(gè)文件,文件名為該SPI接口的全限定名。文件內(nèi)容是 key=具體實(shí)現(xiàn)類的全限定名,如果有多個(gè),則用分行符分隔。
3、測(cè)試,加載實(shí)現(xiàn)類
在 代碼中通過 org.apache.dubbo.common.extension.ExtensionLoader來加載具體的實(shí)現(xiàn)類。
@Test
public void test() {
ExtensionLoader
MyLog myLogback = extensionLoader.getExtension("myLogback");
System.out.println("MyLog 指定名稱的擴(kuò)展點(diǎn):" + myLogback);
myLogback.debug();
// 獲取實(shí)現(xiàn)了@Adaptive注解的實(shí)現(xiàn)類
System.out.println("MyLog 自適應(yīng)擴(kuò)展點(diǎn):" + extensionLoader.getAdaptiveExtension());
System.out.println("MyLog 默認(rèn)擴(kuò)展點(diǎn)協(xié)議:" + extensionLoader.getDefaultExtension());
System.out.println("MyLog 獲取所有擴(kuò)展點(diǎn):" + extensionLoader.getSupportedExtensions());
}
– 求知若饑,虛心若愚。
柚子快報(bào)邀請(qǐng)碼778899分享:Dubbo SPI機(jī)制使用
參考閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。