Feign原始碼解析 執行過程

2021-09-11 14:04:57 字數 4525 閱讀 1646

不了解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的實現類來做的。例如ribbonloadbalancerfeignclient

到此為止,feign的配置和執行流程已經簡單的說完了。

原因就是spring掃瞄了@feignclient註解,並且根據配置的資訊生成**類,呼叫的介面實際上呼叫的是生成的**類。

掃瞄@enablefeignclients註解中配置包路徑。

掃瞄@feignclient註解,並將註解配置的資訊注入到spring容器中,型別為feignclientfactorybean

根據feignclientfactorybeangetobject()方法得到不同動態**的類。

根據不同的**執行不同的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的方式進行...