千家信息网

spring cloud openfeign中Targeter的原理和作用是什么

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,这篇文章主要介绍"spring cloud openfeign中Targeter的原理和作用是什么",在日常操作中,相信很多人在spring cloud openfeign中Targeter的原理和作
千家信息网最后更新 2025年12月02日spring cloud openfeign中Targeter的原理和作用是什么

这篇文章主要介绍"spring cloud openfeign中Targeter的原理和作用是什么",在日常操作中,相信很多人在spring cloud openfeign中Targeter的原理和作用是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"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 target(FeignClientFactoryBean factory, Feign.Builder feign,                        FeignContext context, Target.HardCodedTarget 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 target(FeignClientFactoryBean factory, Feign.Builder feign,                        FeignContext context, Target.HardCodedTarget 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 {  /* The type of the interface this target applies to. ex. {@code Route53}. */  Class 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 implements Target {    private final Class type;    private final String name;    private final String url;    public HardCodedTarget(Class type, String url) {      this(type, url, url);    }    public HardCodedTarget(Class 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 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 target(FeignClientFactoryBean factory, Feign.Builder feign,                        FeignContext context, Target.HardCodedTarget 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 targetWithFallbackFactory(String feignClientName, FeignContext context,                        Target.HardCodedTarget target, HystrixFeign.Builder builder,                        Class fallbackFactoryClass) {                FallbackFactory fallbackFactory = (FallbackFactory) getFromContext(                                "fallbackFactory", feignClientName, context, fallbackFactoryClass,                                FallbackFactory.class);                return builder.target(target, fallbackFactory);        }        private  T targetWithFallback(String feignClientName, FeignContext context,                        Target.HardCodedTarget target, HystrixFeign.Builder builder,                        Class fallback) {                T fallbackInstance = getFromContext("fallback", feignClientName, context,                                fallback, target.type());                return builder.target(target, fallbackInstance);        }        private  T getFromContext(String fallbackMechanism, String feignClientName,                        FeignContext context, Class beanType, Class 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 getOptional(String feignClientName, FeignContext context,                        Class 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)返回

到此,关于"spring cloud openfeign中Targeter的原理和作用是什么"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0