@FeignClient使用

微服务系统内部服务相互调用使用spring-cloud-openfeign-core 的FeignClient

源码如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface FeignClient {
    @AliasFor("name")
    String value() default "";

    String contextId() default "";

    @AliasFor("value")
    String name() default "";

    /** @deprecated */
    @Deprecated
    String qualifier() default "";

    String[] qualifiers() default {};

    String url() default "";

    boolean decode404() default false;

    Class<?>[] configuration() default {};

    Class<?> fallback() default void.class;

    Class<?> fallbackFactory() default void.class;

    String path() default "";

    boolean primary() default true;
}
name,value @AliasFor 表示字段互为别名。如果没有配置url那么配置的值将作为服务名称,用于服务发现。反之只是一个名称。
在项目中如果存在相同的
FeignClient 需要指定不同的contextId,获取服务名称顺序:contextId->value->name->serviceId
private String getClientName(Map<String, Object> client) {
    if (client == null) {
      return null;
    }
    String value = (String) client.get("contextId");
    if (!StringUtils.hasText(value)) {
      value = (String) client.get("value");
    }
    if (!StringUtils.hasText(value)) {
      value = (String) client.get("name");
    }
    if (!StringUtils.hasText(value)) {
      value = (String) client.get("serviceId");
    }
    if (StringUtils.hasText(value)) {
      return value;
    }

    throw new IllegalStateException("Either 'name' or 'value' must be provided in @"
        + FeignClient.class.getSimpleName());
  }

url: 用于指定服务地址  如果为空表示在当前服务集群中

decode404: 当调用请求发生404错误时,decode404的值为true,那么会执行decoder解码,否则抛出异常

configuration: Feign配置类  如 configuration = FeignClientProperties.FeignClientConfiguration.class

fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口

fallbackFactory: 工厂类,用于生成fallback类示例

path: 定义当前接口请求的统一前缀。

 

当我们跨集群去调用服务时,这是就需要动态创建FeignClient的调用 

spring-cloud-openfeign-core包下提供了FeignClientBuilder类,可以在不使用@FeignClient手动生成FeignClient。

代码如下:

@Component
public class DynamicFeignClientFactory<T> {

    private FeignClientBuilder feignClientBuilder;

    public DynamicFeignClientFactory(ApplicationContext appContext) {
        this.feignClientBuilder = new FeignClientBuilder(appContext);
    }

    public T getFeignClient(final Class<T> type, String serviceName, String url) {
        return this.feignClientBuilder
                .forType(type, serviceName)
                .url(url)
                .build();
    }

}

 

 

 

 

posted @ 2023-02-17 16:02  山阴路的秋天  阅读(437)  评论(0)    收藏  举报