本篇文章是dubbo SPI源碼分析的第二篇,接着第一篇繼續分析dubbo SPI的內容,咱們主要介紹 getDefaultExtension() 獲取默認擴展點方法。源碼分析
因爲此方法比較簡單,咱們略過示例部分,直接分析源碼。spa
獲取默認擴展方法getDefaultExtension()是一個public、可對外提供調用的方法。咱們知道,dubbo中擴展點接口必需要有@SPI註解修飾,@SPI註解代碼以下:code
1 @Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target({ElementType.TYPE}) 4 public @interface SPI { 5 6 /** 7 * default extension name 8 */ 9 String value() default ""; 10 11 }
註解能夠修飾類和接口,同時提供 一個默認爲空的value字段。對象
這個value字段 就是本篇文章要介紹的默認擴展實現。blog
如今咱們來看getDefaultExtension()方法內部:接口
1 public T getDefaultExtension() { 2 getExtensionClasses(); 3 // cachedDefaultName爲@SPI中的value 4 if (null == cachedDefaultName || cachedDefaultName.length() == 0 || "true".equals(cachedDefaultName)) { 5 return null; 6 } 7 return getExtension(cachedDefaultName); 8 }
第二行方法 getExtensionClasses()是加載配置文本文件,獲取配置的擴展點實現類,方法執行完,會把配置文本文件的key和擴展點實現類的Class對象存儲在cachedClasses 成員變量中,這個咱們在第一篇已經介紹過。字符串
接下來就是方法的關鍵點,成員變量cachedDefaultName 的判斷了,若是cachedDefaultName 爲空或爲」true「 直接返回 null,若是cachedDefaultName 不爲空,則調用getExtension(..)方法,返回擴展點實現類對象。這個方法咱們在第一篇也已經介紹了。如今咱們只須要分析cachedDefaultName的賦值點 就ok 了。get
成員變量cachedDefaultName 咱們在第一篇有介紹到,不知道你們是否還有印象,咱們如今看看變量定義:源碼
1 // SPI()內value,默認的接口實現 2 private String cachedDefaultName;
私有的字符串變量。it
變量cachedDefaultName的賦值,咱們先提早介紹下,其實就是在加載配置文本文件的過程當中進行的,具體的方法調用鏈爲:
1 getDefaultExtension() -->getExtensionClasses()-->loadExtensionClasses()
這幾個方法咱們都有介紹,咱們如今看看loadExtensionClasses():
1 private Map<String, Class<?>> loadExtensionClasses() { 2 // 獲取註解 SPI的接口 3 // type爲傳入的擴展接口,必須有@SPI註解 4 final SPI defaultAnnotation = type.getAnnotation(SPI.class); 5 // 獲取默認擴展實現value,若是存在,賦值給cachedDefaultName 6 if (defaultAnnotation != null) { 7 String value = defaultAnnotation.value(); 8 if ((value = value.trim()).length() > 0) { 9 // @SPI value 只能是一個,不能爲逗號分割的多個 10 // @SPI value爲默認的擴展實現 11 String[] names = NAME_SEPARATOR.split(value); 12 if (names.length > 1) { 13 throw new IllegalStateException("more than 1 default extension name on extension " + type.getName() + ": " + Arrays.toString(names)); 14 } 15 if (names.length == 1) 16 cachedDefaultName = names[0]; 17 } 18 } 19 // 加載三個目錄配置的擴展類 20 Map<String, Class<?>> extensionClasses = new HashMap<String, Class<?>>(); 21 // META-INF/dubbo/internal 22 loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY); 23 // META-INF/dubbo 24 loadDirectory(extensionClasses, DUBBO_DIRECTORY); 25 // META-INF/services/ 26 loadDirectory(extensionClasses, SERVICES_DIRECTORY); 27 return extensionClasses; 28 }
沒錯,對cachedDefaultName的賦值,僅此一出。
cachedDefaultName的內容就是解析@SPI註解的value內容。此處賦值後,getDefaultExtension()方法的返回就是根據這個值進行擴展點獲取並返回的。
獲取默認擴展點的方法getDefaultExtension() 邏輯很簡單,就是解析出註解@SPI的value內容,經過前一篇介紹的getExtension(..)方法進行擴展點獲取。若是@SPI沒有配置value或者設置的是」true「,getDefaultExtension()方法返回的就是null。