前言
通過對feign的使用,發現@enablefeignclients和@feignclient兩個註解就實現了feign的功能,那就從
@enablefeignclients註解開始分析feign的原始碼
1、enablefeignclients註解
@retention
(retentionpolicy.runtime)
@target()
@documented
@import()
public @inte***ce
enablefeignclients
通過 @enablefeignclients 引入了feignclientsregistrar客戶端註冊類
2、feignclientsregistrar註冊類
public
void
registerbeandefinitions
(annotationmetadata metadata, beandefinitionregistry registry)
通過其類結構可知,由於實現了importbeandefinitionregistrar介面,那麼就會自動執行
registerbeandefinitions()中的註冊物件,主要註冊的物件型別有兩種:
1)、註冊預設配置的配置資訊
2)、註冊那些新增了@feignclient的類或介面 : 這也是我們討論的重點
classpathscanningcandidatecomponentprovider scanner =
this
.getscanner()
; scanner.
setresourceloader
(this
.resourceloader)
; map
attrs = metadata.
getannotationattributes
(enablefeignclients.
class
.getname()
);annotationtypefilter annotationtypefilter =
newannotationtypefilter
(feignclient.
class);
class<
?>
clients = attrs == null ? null :
(class)
((class[
])attrs.
get(
"clients"))
; object basepackages;
if(clients != null && clients.length !=0)
abstractclasstestingtypefilter filter =
newabstractclasstestingtypefilter()
};scanner.
addincludefilter
(new
feignclientsregistrar.alltypefilter
(arrays.
aslist
(filter, annotationtypefilter)))
;}else
iterator var17 =
((set)basepackages)
.iterator()
;while
(var17.
hasnext()
)}}}
該方法主要是掃瞄類路徑,對所有的feignclient生成對應的 beandefinitio 。同時又呼叫了
registerclientconfiguration 註冊配置的方法,這裡是第二處呼叫。這裡主要是將掃瞄的目錄下,
每個專案的配置類載入的容器當中。呼叫 registerfeignclient 註冊物件
其中mapattrs = metadata.getannotationattributes(enablefeignclients.class.getname());便是掃瞄@enablefeignclients註解
3、註冊feignclient物件
private
void
registerfeignclient
(beandefinitionregistry registry, annotationmetadata annotationmetadata, map
attributes)
beandefinitionholder holder =
newbeandefinitionholder
(beandefinition, classname,
newstring
);beandefinitionreaderutils.
registerbeandefinition
(holder, registry)
;}
通過分析可知:最終是向spring中註冊了乙個bean,bean的名稱就是類或介面的名稱(也就是本
例中的feignservice),bean的實現類是feignclientfactorybean,其屬性設定就是在
@feignclient中定義的屬性。那麼下面在controller中對feignservice的的引入,實際就是引入了
feignclientfactorybean 類
4、feignclientfactorybean類
對@enablefeignclients註解的原始碼進行了分析,了解到其主要作用就是把帶有@feignclient註解的
類或介面用feignclientfactorybean類註冊到spring中。
class
feignclientfactorybean
implements
factorybean
public object getobject()
throws exception
//略}
t gettarget()
else
this
.url =
this
.url +
this
.cleanpath()
;return
this
.loadbalance
(builder, context,
newhardcodedtarget
(this
.type,
this
.name,
this
.url));
}else
string url =
this
.url +
this
.cleanpath()
; client client =
(client)
this
.getoptional
(context, client.
class);
if(client != null)
builder.
client
(client);}
targeter targeter =
(targeter)
this
.get
(context, targeter.
class);
return targeter.
target
(this
, builder, context,
newhardcodedtarget
(this
.type,
this
.name, url));
}}
Feign原始碼分析
feign主要圍繞註解 feignclient和 autowired來分析就好了,feignclient是註解在乙個介面上面的,這個註解是乙個標誌,相應的後置處理器把有該標誌的類加入到bean defenition中。autowired是注入屬性的,feign採用的是factorybean的方式進行...
Feign原始碼解析
首先我要說的是springcloud沒有rpc,這就涉及rpc和微服務的區別。springcloud的模組通訊工具feign跟httpclient和okhttp是一樣的東西,都是對http請求封裝的工具,其實feign可以選擇httpclient或者okhttp作為底層實現 修改配置即可 一 fei...
feign原始碼解讀
對於feign的介面請求失敗的重試配置可通過如下自定義配置檔案實現 一般不建議配置 configuration public class feignconfig 當然,也可使用預設的retry配置檔案,下方是feign.retryer的原始碼 類的全路徑是feign.retryer public d...