不了解factorybean
介面的,可以看如何使用spring的factorybean介面
作為乙個實現了factorybean
的工廠類,那麼每次在spring context 建立實體類的時候會呼叫它的getobject()
方法。
class feignclientfactorybean implements factorybean, initializingbean,
private class<?> type;
private string name;
private string url;
private string path;
private boolean decode404;
private class<?> fallback = void.class;
private class<?> fallbackfactory = void.class;
-------其餘**省略
} -------其餘**省略
}複製**
這裡的getobject()
其實就是將@feinclient
中設定value值進行組裝起來,此時或許會有疑問,因為在配置feignclientfactorybean
類時特意說過並沒有將configuration傳過來,那麼configuration中的屬性是如何配置的呢?看其第一句是
複製**
意思就是從spring容器中獲取feigncontext.class
的類,我們可以看下這個類是從哪載入的。我們可以看feignautoconfiguration
此類,原始碼如下,我們可以看到在此類中自動配置了feigncontext
類,並且將feignclientspecification
型別的類全部加入此類的屬性中。
@configuration
@conditionalonclass(feign.class)
@enableconfigurationproperties()
public class feignautoconfiguration
@bean
public feigncontext feigncontext
() @configuration
@conditionalonclass(name = "feign.hystrix.hystrixfeign")
protected static class hystrixfeigntargeterconfiguration
} @configuration
@conditionalo****singclass("feign.hystrix.hystrixfeign")
protected static class defaultfeigntargeterconfiguration
}-------省略
}複製**
至此我們已經完成了配置屬性的裝配工作,那麼是如何執行的呢?我們可以看getobject()
最後一句可以看到返回了targeter.target
的方法。
return targeter.target(this, builder, context, new hardcodedtarget<>(
this.type, this.name, url));
複製**
那麼這個targeter
是哪來的?我們還是看上面的feignautoconfiguration
類,可以看到其中有兩個targeter
類,乙個是defaulttargeter
,乙個是hystrixtargeter
。當配置了feign.hystrix.enabled= true
的時候,spring容器中就會配置hystrixtargeter
此類,如果為false那麼spring容器中配置的就是defaulttargeter
我們以defaulttargeter
為例介紹一下接下啦是如何通過建立**物件的
class defaulttargeter implements targeter
}public static class builder
public feign build
() }
複製**
檢視reflectivefeign
類中newinstance
方法是返回乙個**物件
public t newinstance(targettarget) else
if(util.isdefault(method)) else
}//設定***
invocationhandler handler = factory.create(target, methodtohandler);
t proxy = (t) proxy.newproxyinstance(target.type().getclassloader(), new class<?>, handler);
for(defaultmethodhandler defaultmethodhandler : defaultmethodhandlers)
return proxy;
}複製**
最終都是執行了synchronousmethodhandler
***中的invoke
方法
@override
public object invoke(object ar**) throws throwable catch (retryableexception e)
continue;}}
}複製**
invoke
方法方法主要是應用 encoder,decoder 以及 retry 等配置, 並且自身對於呼叫結果有一定的處理邏輯。我們最關心的請求實現,實際上是在組裝 synchronousmethodhandler 的 client 引數上,即前面提到的,如果當前路徑裡面有 ribbon,就是 loadbalancerfeignclient,如果沒有,根據配置生成 apachehttpclient 或者 okhttpclient。在 ribbon 裡面,實現了 eureka 服務發現以及進行請求等動作。當然 ribbon 裡面還帶了負載均衡邏輯。
synchronousmethodhandler
其實是不關心呼叫過程的,他只是處理呼叫的結果。呼叫過程是實現了client
的實現類來做的。例如ribbon
的loadbalancerfeignclient
。
到此為止,feign的配置和執行流程已經簡單的說完了。
原因就是spring掃瞄了@feignclient
註解,並且根據配置的資訊生成**類,呼叫的介面實際上呼叫的是生成的**類。
掃瞄@enablefeignclients
註解中配置包路徑。
掃瞄@feignclient
註解,並將註解配置的資訊注入到spring容器中,型別為feignclientfactorybean
。
根據feignclientfactorybean
的getobject()
方法得到不同動態**的類。
根據不同的**執行不同的invoke()
方法。
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...
Feign原始碼分析
feign主要圍繞註解 feignclient和 autowired來分析就好了,feignclient是註解在乙個介面上面的,這個註解是乙個標誌,相應的後置處理器把有該標誌的類加入到bean defenition中。autowired是注入屬性的,feign採用的是factorybean的方式進行...