Spring Cloud架構 - Open Feign源碼解析(一)

源碼解析 - 註冊bean

@EnableFeignClients開始分析。

在這裏插入圖片描述

@EnableFeignClients的作用是掃描標註@FeignClient註解的所有接口。

現在重點關注下FeignClientRegistrar這個類。

它重寫了ImportBeanDefinitionRegistrar接口的如下方法:
在這裏插入圖片描述

這個方法用來在上下文中註冊BeanDefinitions。

先來看下第一部分的registerDefaultConfiguration(...)方法。
在這裏插入圖片描述

首先是獲取@EnableFeignClients註解的屬性以及屬性值。

如果有設置defaultConfiguration屬性值,執行registerClientConfiguration(…)方法。

在這裏插入圖片描述

首先是構造了一個BeanDefinitionBuilder實例。

現在來看下如何構造的。

在這裏插入圖片描述

實際上就是GenericBeanDefinition調用setBeanClass(Class<?> beanClass)方法。這裏的方法的參數beanClass就是FeignClientSpefication.class。

接下來看:
在這裏插入圖片描述

實際上是調用ConstructorArgumentValues的addIndexedArgumentValue(…)方法。它會重寫原有的屬性值

第一個參數是構造器中的參數下標,第二個參數是參數對應的值。

最後還剩下,如下方法:
在這裏插入圖片描述

註冊BeanDefinition。

在這裏插入圖片描述

這個是屬於Spring框架的在上下文中註冊bean方法。(這裏不展開解析。)

第二部分分析下registerFeignClients(…)方法

構造一個ClassPathScanningCandidateComponentProvider實例。

ClassPathScanningCandidateComponentProvider scanner = getScanner();

在這裏插入圖片描述

重寫了isCandidateComponent方法。對於bean定義中的元數據屬於independent,但是不是個註解,就會符合候選的條件。

isIndepent方法,定義如下:
在這裏插入圖片描述

設置ResourceLoader。

scanner.setResourceLoader(this.resourceLoader);

獲取@EnableFeignCients註解的所有屬性以及相關屬性值。

Map<String, Object> attrs = metadata
				.getAnnotationAttributes(EnableFeignClients.class.getName());

構造了一個AnnotationTypeFilter實例

AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
				FeignClient.class);

而AnnotationTypeFilter,定義如下:
在這裏插入圖片描述

獲取@EnableFeignClients註解的clients屬性值

final Class<?>[] clients = attrs == null ? null
				: (Class<?>[]) attrs.get("clients");

這個屬性在@EnableFeignClients註解定義如下:
在這裏插入圖片描述

如果沒有設置clients屬性,在TypeFilter列表中添加指定的AnnotationTypeFilter

在這裏插入圖片描述

獲取@EnableFeignClients註解中設置的指定包
在這裏插入圖片描述

再看下@EnableFeignClients註解的value、basePackages、basePackageClasses屬性值。

在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

如果有設置clients屬性,執行如下

在這裏插入圖片描述

然後會遍歷basePackages。如下:
在這裏插入圖片描述

要求@FeignClient註解標註在接口上。

獲取@FeignClient註解的contextId、value、name、serviceId屬性作爲指定的名字
在這裏插入圖片描述

註冊@FeignClient註解指定的配置類

registerClientConfiguration(registry, name,
							attributes.get("configuration"));

方法具體的處理,上面有分析。這裏不再重複。

註冊標註@FeignClient的接口

registerFeignClient(registry, annotationMetadata, attributes);

構造一個BeanDefinitionHolder實例進行註冊
在這裏插入圖片描述
在這裏插入圖片描述

除了註冊bean定義之外,還會註冊別名
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章