一、前言
學(xué)習(xí)dubbo源碼時,Dubbo的SPI機制必須先了解,不然閱讀Dubbo源碼會非常困難
二、使用
1.首先看基礎(chǔ)使用方式
ExtensionLoader.getExtensionLoader(Class<T> type).getExtension(String name);
配置文件放在META-INF\dubbo\目錄下,文件名稱以 type 接口全限定名為名稱
aaa=com.xxx.aaa
bbb=com.xxx.bbb
當(dāng)方法傳入 type= 接口名稱,name = aaa 時,我們獲取到的實例就是 com.xxx.aaa
2.adaptiveExtension使用方式
ExtensionLoader.getExtensionLoader(Class<T> type).getAdaptiveExtension()
當(dāng)接口中有一個類的實現(xiàn)類上,使用了@Adaptive注解,則會獲取到該類的實例
如果當(dāng)前接口沒有一個實現(xiàn)類使用了@Adaptive注解,則需要該接口的一個方法上使用@Adaptive注解,然后給定參數(shù)名稱;
當(dāng)調(diào)用getAdaptiveExtension方法時,會獲取到 type的一個動態(tài)代理類(有興趣的可以去看下這個動態(tài)代理類的實現(xiàn)方式,直接使用動態(tài)代碼編譯的,既不是用的JDK的動態(tài)代理,也不是用的CGLIB動態(tài)代理),然后該類必須要有一個參數(shù),類型為URL或者該參數(shù)有g(shù)etUrl這個方法,在調(diào)用時,會根據(jù)url中,@Adaptive注解上指定參數(shù)名稱來獲取 擴展類,調(diào)用該方法;
3.包裝類型
如果我們再配置文件中,添加一個該接口的一個實現(xiàn)類,該實現(xiàn)類的構(gòu)造方法參數(shù)為該接口類型;
public class TestWrapper implements TestService{
private TestService testService;
public TestWrapper (TestService testService){
this.testService = testService;
}
@Override
public String sayHello() {
//xxx前置方法
String Result = testService.sayHello();
//xxx后置方法
return Result;
}
}
配置文件META-INF\dubbo\com.xxx.TestService如下
aaa=com.xxx.aaa
bbb=com.xxx.bbb
com.xxx.TestWrapper
我們再使用第一種方法獲取aaa時,則獲取到的是TestWrapper 對象,該對象testService屬性值為 aaa的實例,這樣就可以做很多增強操作,和aop類似;