@FeignClient常用属性

java @FeignClient(name = "gateway-test", value = "gateway-test", url = "localhost:9997", fallbackFactory = FallbackFactory.class, contextId = "GatewayClient")

name/value: 服务名称

```java //查看源码可知: 两个属性等价 public @interface FeignClient { @AliasFor("value") String name() default "";

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

} //查看源码可知: 两个属性至少要配置一个 FeignClientsRegistrar { private String getClientName(Map 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: 请求地址, 没配置的话, 会把name/value的属性值当成服务名进行调用, 配置的话则使用url的值

示例:

image

Product服务: 服提供者, 服务名product-client, 存在一个接口/product/test, 返回"test"字符串

User服务: 调用方, 服务名user-client, 存在一个接口/user/test, 调用product服务的test接口

```java //配置url方式,请求地址为url的地址 @FeignClient(name = "product-client", url = "localhost:9997") public interface ProductClient {

/**
 *  ..
 * @return .
 */
@GetMapping("/product/test")
String test();

}

@RequestMapping("/user") public class UserController {

@Resource
private ProductClient client;

@GetMapping("/test")
public String test() {
    return client.test();
}

}
//访问http://localhost:8200/user/test报错: //Connection refused: connect executing GET http://localhost:9997/product/test with root cause //说明配置了url属性后,确实是根据url的值作为请求地址进行调用 ```

```java //使用服务名调用方式 @FeignClient(name = "product-client") public interface ProductClient {

/**
 *  ..
 * @return .
 */
@GetMapping("/product/test")
String test();

} //调用成功,后台能看到获取注册中心(nacos)的数据解析获取真实的url地址的日志 ```

image

```java //用一个不存在的服务名再验证一下 @FeignClient(name = "product-client123") public interface ProductClient {

/**
 *  ..
 * @return .
 */
@GetMapping("/product/test")
String test();

} //报错信息: com.netflix.client.ClientException: Load balancer does not have available server for client: product-client123 ```

fallbackFactory: 获取异常信息

示例:

```java user服务开启hystrix feign: hystrix: enabled: true

//user服务添加fallback,用于在调用服务出现错误时,返回自定义信息 @Component public class ProductClientFallback implements ProductClient{ @Override public String test() { return "error"; } }

//user服务添加fallbackFactory,用户在调用服务出现错误时,获取错误信息 @Component public class ProductClientFallbackFactory implements FallbackFactory { @Resource ProductClientFallback fallback; @Override public ProductClient create(Throwable cause) { System.out.println("cause.getMessage() = " + cause.getMessage()); return fallback; } }

//product服务修改/product/test接口,模拟出现异常 @RestController @RequestMapping("/product") public class ProductController { @GetMapping("/test") public String test() throws Exception { throw new Exception("test Exception"); } }
```

Postman访问 http://localhost:8200/user/test ,成功返回自定义的异常信息

image

查看服务调用方User的日志, 成功打印出错误日志

image

message信息为空的话,配置一下Product服务:

yaml server: error: include-message: ALWAYS

具体原因请查看 博客, 也可以通过使用@ControllerAdvice来解决

contextId: 别名

假设一个User服务有两个FeignClient,都需要调用Product服务, 因为name属性值一样,所以需要通过配置contextId来区分,否则启动项目时会报错

```java @FeignClient(name = "product-client", fallbackFactory = ProductClientFallbackFactory.class, contextId = "ProductClientCopy") public interface ProductClientCopy {

/**
 *  ..
 * @return .
 */
@GetMapping("/product/testCopy")
String test();

}

@FeignClient(name = "product-client", fallbackFactory = ProductClientFallbackFactory.class, contextId = "ProductClient") public interface ProductClient {

/**
 *  ..
 * @return .
 */
@GetMapping("/product/testCopy")
String test();

} ```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值