您好,登錄后才能下訂單哦!
這篇文章主要介紹“spring cloud openfeign中Targeter的原理和作用是什么”,在日常操作中,相信很多人在spring cloud openfeign中Targeter的原理和作用是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”spring cloud openfeign中Targeter的原理和作用是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
本文主要研究一下spring cloud openfeign的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類型的參數
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方法
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方法
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返回
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
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)返回
到此,關于“spring cloud openfeign中Targeter的原理和作用是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。