聊聊spring cloud openfeign的Targeter
序
本文主要研究一下spring cloud openfeign的Targeter
Targeter
spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/Targeter.java
interface Targeter { <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context, Target.HardCodedTarget<T> target); }
- Targeter定義了target方法,它接收FeignClientFactoryBean、Feign.Builder、FeignContext、Target.HardCodedTarget型別的引數
DefaultTargeter
spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/DefaultTargeter.java
class DefaultTargeter implements Targeter { @Override public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context, Target.HardCodedTarget<T> target) { return feign.target(target); } }
- DefaultTargeter實現了Targeter介面,它的target方法直接使用的是Feign.Builder.target方法
Target
feign-core-10.2.3-sources.jar!/feign/Target.java
public interface Target<T> { /* The type of the interface this target applies to. ex. {@code Route53}. */ Class<T> type(); /* configuration key associated with this target. For example, {@code route53}. */ String name(); /* base HTTP URL of the target. For example, {@code https://api/v2}. */ String url(); public Request apply(RequestTemplate input); //...... }
- Target介面定義了type、name、url、apply方法
HardCodedTarget
feign-core-10.2.3-sources.jar!/feign/Target.java
public static class HardCodedTarget<T> implements Target<T> {
private final Class<T> type;
private final String name;
private final String url;
public HardCodedTarget(Class<T> type, String url) {
this(type, url, url);
}
public HardCodedTarget(Class<T> type, String name, String url) {
this.type = checkNotNull(type, "type");
this.name = checkNotNull(emptyToNull(name), "name");
this.url = checkNotNull(emptyToNull(url), "url");
}
@Override
public Class<T> type() {
return type;
}
@Override
public String name() {
return name;
}
@Override
public String url() {
return url;
}
/* no authentication or other special activity. just insert the url. */
@Override
public Request apply(RequestTemplate input) {
if (input.url().indexOf("http") != 0) {
input.target(url());
}
return input.request();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof HardCodedTarget) {
HardCodedTarget<?> other = (HardCodedTarget) obj;
return type.equals(other.type)
&& name.equals(other.name)
&& url.equals(other.url);
}
return false;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + type.hashCode();
result = 31 * result + name.hashCode();
result = 31 * result + url.hashCode();
return result;
}
@Override
public String toString() {
if (name.equals(url)) {
return "HardCodedTarget(type=" + type.getSimpleName() + ", url=" + url + ")";
}
return "HardCodedTarget(type=" + type.getSimpleName() + ", name=" + name + ", url=" + url
+ ")";
}
}
- HardCodedTarget實現了Target介面,其構造器接收type、name、url引數,其apply方法對於url是http開頭的則設定RequestTemplate的target為url,然後構造request返回
HystrixTargeter
spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/HystrixTargeter.java
class HystrixTargeter implements Targeter {
@Override
public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign,
FeignContext context, Target.HardCodedTarget<T> target) {
if (!(feign instanceof feign.hystrix.HystrixFeign.Builder)) {
return feign.target(target);
}
feign.hystrix.HystrixFeign.Builder builder = (feign.hystrix.HystrixFeign.Builder) feign;
SetterFactory setterFactory = getOptional(factory.getName(), context,
SetterFactory.class);
if (setterFactory != null) {
builder.setterFactory(setterFactory);
}
Class<?> fallback = factory.getFallback();
if (fallback != void.class) {
return targetWithFallback(factory.getName(), context, target, builder,
fallback);
}
Class<?> fallbackFactory = factory.getFallbackFactory();
if (fallbackFactory != void.class) {
return targetWithFallbackFactory(factory.getName(), context, target, builder,
fallbackFactory);
}
return feign.target(target);
}
private <T> T targetWithFallbackFactory(String feignClientName, FeignContext context,
Target.HardCodedTarget<T> target, HystrixFeign.Builder builder,
Class<?> fallbackFactoryClass) {
FallbackFactory<? extends T> fallbackFactory = (FallbackFactory<? extends T>) getFromContext(
"fallbackFactory", feignClientName, context, fallbackFactoryClass,
FallbackFactory.class);
return builder.target(target, fallbackFactory);
}
private <T> T targetWithFallback(String feignClientName, FeignContext context,
Target.HardCodedTarget<T> target, HystrixFeign.Builder builder,
Class<?> fallback) {
T fallbackInstance = getFromContext("fallback", feignClientName, context,
fallback, target.type());
return builder.target(target, fallbackInstance);
}
private <T> T getFromContext(String fallbackMechanism, String feignClientName,
FeignContext context, Class<?> beanType, Class<T> targetType) {
Object fallbackInstance = context.getInstance(feignClientName, beanType);
if (fallbackInstance == null) {
throw new IllegalStateException(String.format(
"No " + fallbackMechanism
+ " instance of type %s found for feign client %s",
beanType, feignClientName));
}
if (!targetType.isAssignableFrom(beanType)) {
throw new IllegalStateException(String.format("Incompatible "
+ fallbackMechanism
+ " instance. Fallback/fallbackFactory of type %s is not assignable to %s for feign client %s",
beanType, targetType, feignClientName));
}
return (T) fallbackInstance;
}
private <T> T getOptional(String feignClientName, FeignContext context,
Class<T> beanType) {
return context.getInstance(feignClientName, beanType);
}
}
- HystrixTargeter實現了Targeter介面,其target方法首先判斷Feign.Builder型別是否是feign.hystrix.HystrixFeign.Builder,不是的話直接執行feign.target(target)返回
- 對於fallback不為void.class的使用targetWithFallback進行構造;對於fallbackFactory不為void.class的使用targetWithFallbackFactory進行構造;都不是的話則執行feign.target(target)返回
- targetWithFallbackFactory方法使用HystrixFeign.Builder的target進行構造時使用的是fallbackFactory;而targetWithFallback方法使用的是fallbackInstance
FeignAutoConfiguration
spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/FeignAutoConfiguration.java
@Configuration
@ConditionalOnClass(Feign.class)
@EnableConfigurationProperties({ FeignClientProperties.class,
FeignHttpClientProperties.class })
public class FeignAutoConfiguration {
//......
@Configuration
@ConditionalOnClass(name = "feign.hystrix.HystrixFeign")
protected static class HystrixFeignTargeterConfiguration {
@Bean
@ConditionalOnMissingBean
public Targeter feignTargeter() {
return new HystrixTargeter();
}
}
@Configuration
@ConditionalOnMissingClass("feign.hystrix.HystrixFeign")
protected static class DefaultFeignTargeterConfiguration {
@Bean
@ConditionalOnMissingBean
public Targeter feignTargeter() {
return new DefaultTargeter();
}
}
//......
}
- FeignAutoConfiguration在有feign.hystrix.HystrixFeign時建立的是HystrixTargeter,否則建立的是DefaultTargeter
小結
- Targeter定義了target方法,它接收FeignClientFactoryBean、Feign.Builder、FeignContext、Target.HardCodedTarget型別的引數
- DefaultTargeter實現了Targeter介面,它的target方法直接使用的是Feign.Builder.target方法
- HystrixTargeter實現了Targeter介面,其target方法首先判斷Feign.Builder型別是否是feign.hystrix.HystrixFeign.Builder,不是的話直接執行feign.target(target)返回;否則對於fallback不為void.class的使用targetWithFallback進行構造;對於fallbackFactory不為void.class的使用targetWithFallbackFactory進行構造;都不是的話則執行feign.target(target)返回
doc
-
相關推薦
從架構演進的角度聊聊spring cloud都做了些什麽?
將不 技術選型 ati 繼續 微服務 公司 發現 dashboard 整合 Spring Cloud作為一套微服務治理的框架,幾乎考慮到了微服務治理的方方面面,之前也寫過一些關於Spring Cloud文章,主要偏重各組件的使用,本次分享主要解答這兩個問題:Spring C
Spring Cloud 入門教程:聊聊Spring Cloud
一、 Spring Cloud 是什麼? Spring Cloud 是將分散式系統中一系列基礎框架/工具進行整合的框架。其中包含:服務註冊與發現、服務閘道器、熔斷器、配置中心、訊息中心、服務鏈路追蹤等等。 Spring Cloud 並沒有重複造輪子,Spring Cloud只是依賴於Spring Boo
從架構演進的角度聊聊Spring Cloud做了些什麼
傳統架構發展史 單體架構 單體架構在小微企業比較常見,典型代表就是一個應用、一個數據庫、一個web容器就可以跑起來,比如我們開發的開源軟體雲收藏,就是標準的單體架構。 在兩種情況下可能會選擇單體架構:一是在企業發展的初期,為了保證快速上線,採用此種方案較為簡單靈活;二是傳統企業中垂直度較
聊聊spring cloud netflix ribbon的eager load
RibbonAutoConfiguration spring-cloud-netflix-ribbon-2.1.1.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java @Conf
聊聊spring cloud的FeignLoadBalancer
序 本文主要研究一下spring cloud的FeignLoadBalancer FeignLoadBalancer spring
聊聊spring cloud的RetryableFeignLoadBalancer
序 本文主要研究一下spring cloud的RetryableFeignLoadBalancer RetryableFeignL
聊聊spring cloud的FeignClientBuilder
序 本文主要研究一下spring cloud的FeignClientBuilder FeignClientBuilder spri
聊聊spring cloud的FeignClientFactoryBean
序 本文主要研究一下spring cloud的FeignClientFactoryBean FeignClientFactoryB
聊聊spring cloud openfeign的Targeter
序 本文主要研究一下spring cloud openfeign的Targeter Targeter spring-cloud-o
聊聊spring cloud的CachingSpringLoadBalancerFactory
序 本文主要研究一下spring cloud的CachingSpringLoadBalancerFactory CachingSp
聊聊spring cloud的ConsulServiceRegistry
序 本文主要研究一下spring cloud的ConsulServiceRegistry ServiceRegistry spri
聊聊spring cloud consul的TtlScheduler
序 本文主要研究一下spring cloud consul的TtlScheduler TtlScheduler spring-cl
聊聊spring cloud的ConsulCatalogWatch
序 本文主要研究一下spring cloud的ConsulCatalogWatch ConsulCatalogWatch spri
從 Spring Cloud 開始,聊聊微服務架構實踐之路
實施 swa 小時 consul 獲取 交互 大內存 二進制文件 gin 【編者的話】隨著公司業務量的飛速發展,平臺面臨的挑戰已經遠遠大於業務,需求量不斷增加,技術人員數量增加,面臨的復雜度也大大增加。在這個背景下,平臺的技術架構也完成了從傳統的單體應用到微服務化的演進。
聊聊分布式開發 Spring Cloud
dash git pc通信 封裝 dubbo 消息中間件 十分 希望 當前 概述 本文章只是簡單介紹了微服務開發的一些關鍵詞,如果需要知道具體實現和可以評論留言 我會及時的增加連接寫出具體實現(感覺沒人看 就沒寫具體實現)。 持續更新中。。。。。。 SpringClo
Spring Cloud Config(一):聊聊分散式配置中心 Spring Cloud Config
目錄 Spring Cloud Config(一):聊聊分散式配置中心 Spring Cloud Config Spring Cloud Config(二):基於Git搭建配置中心 Spring Cloud Config(三):基於JDBC搭建配置中心 Sprin
聊聊分散式開發 Spring Cloud
概述 本文章只是簡單介紹了微服務開發的一些關鍵詞,如果需要知道具體實現和可以評論留言 我會及時的增加連線寫出具體實現(感覺沒人看 就沒寫具體實現)。 持續更新中。。。。。。 SpringCloud和Dubbo的區別 Dubbo的定位始終是一款基於傳輸層(TCP)的RPC框架,RPC(Remote Pr
從 Spring Cloud 開始,聊聊微服務架構的實踐之路
使用微服務架構開發應用程式,我們實際上是針對一個個微服務進行設計、開發、測試、部署,因為每個服務之間是沒有彼此依賴的,大概的交付流程就像上圖這樣。設計階段: 架構組將產品功能拆分為若干微服務,為每個微服務設計 API 介面(例如 REST API),需要給出 API 文件,包括 API 的名稱、版本、請求引
Spring cloud Eureka 服務治理(高可用服務中心)
image 本地host available png active url 狀態 name spring 在微服務的架構中,我們考慮發生故障的情況,所以在生產環境中我們需要對服務中各個組件進行高可用部署。 Eureka Server 的高可用實際上就是將自己作為服務想其
分布式服務跟蹤及Spring Cloud的實現
在分布式服務架構中,需要對分布式服務進行治理——在分布式服務協同向用戶提供服務時,每個請求都被哪些服務處理?在遇到問題時,在調用哪個服務上發生了問題?在分析性能時,調用各個服務都花了多長時間?哪些調用可以並行執行?……為此,分布式服務平臺就需要提供這樣一種基礎服務——可以記錄每個請求的調用鏈;調用鏈上調用