首页 > 其他分享 >远程调用之@FeignClient注解属性说明

远程调用之@FeignClient注解属性说明

时间:2022-10-20 12:06:13浏览次数:79  
标签:FeignClient 调用 String default user 注解 public name

​Feign​​​是声明性的web服务客户端。它使编写web服务客户端更加容易。通过Feign我们可以实现调用远程服务像调用本地一样便捷。本篇文章主要详细聊聊​​Feign​​​下的一个核心注解​​@FeignClient​​相关属性。

通过查阅@FeignClient源码,可以看到它的注解包括以下属性:

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

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

String contextId() default "";

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

String qualifier() 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

定义当前客户端Client的名称,等同于​​value​​属性。

value

定义当前客户端Client的名称,等同于​​name​​属性。

serviceId

目前​​serviceId​​已经废弃了,直接使用name即可。

contextId

比如我们有个​​user​​服务,但​​user​​服务中有很多个接口,我们不想将所有的调用接口都定义在一个类中,比如​​UserFeignClientA​​、​​UserFeignClentB​​,当不同的​​Feign​​的​​name​​一致的时候,这时候​​Bean​​的名称就会冲突,解决方式可以通过指定不同的​​contextId​​来解决问题,举个栗子:

UserFeignClientA

@FeignClient(name = "user.service", contextId = "userServiceA", url = "${user.service.url}", configuration = UserRemoteConfig.class)
public interface UserFeignClientA {

/**
* 获取用户默认身份信息
*/
@RequestMapping("/user/identity/default")
ResultData<UserVisaIdentity> getDefaultIdentity(@RequestParam("userId") String userId);
}

UserFeignClientB

@FeignClient(name = "user.service", contextId = "userServiceB" url = "${user.service.url}", configuration = UserRemoteConfig.class)
public interface UserFeignClientB {

/**
* 新增大客户信息
*/
@RequestMapping(value = {"/user/identity/saveIdentity"}, method = RequestMethod.POST)
ResultData<UserVisaIdentity> saveIdentity(@RequestBody UserVisaIdentity userVisaIdentity);
}

url

​url​​用于配置指定服务的地址,相当于直接请求这个服务。

path

@FeignClient(name = "template-service", url = "${universal.service.url}", path = "template", configuration = {RemoteErrorDecoder.class})
public interface ITemplateFeignService {

/**
* 多条件查询
*
* @param templateSearchDto 多条件查询
* @return 模板列表
*/
@GetMapping("/search")
ApiResult<PageResult<TemplateVo>> search(@Valid @SpringQueryMap TemplateSearchDto templateSearchDto);
}

​path​​定义当前​​FeignClient​​访问接口时的统一前缀,比如接口地址是/user/get, 如果你定义了前缀是user, 那么具体方法上的路径就只需要写/get 即可。上面将假设​​universal.service.url​​地址为 ​​http://universal.com​​ ,那么调用​​search​​请求地址为:​​universal.com/template/se…​

configuration

​configuration​​是配置​​Feign​​配置类,在配置类中可以自定义​​Feign​​的​​Encoder​​、​​Decoder​​、​​LogLevel​​、​​Contract​​等。

fallback

​fallback​​定义容错的处理类,也就是回退逻辑,​​fallback​​的类必须实现​​Feign Client​​的接口,无法知道熔断的异常信息。比如:

@FeignClient(name = "account-service") 
public interface AccountServiceClient {
@RequestMapping(method = RequestMethod.GET, value = "/accounts/{accountName}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, fallback = AccountServiceClientFallback.class)
String getAccount(@PathVariable("accountName") String accountName);

}

@Component
public class AccountServiceClientFallback implements AccountServiceClient {

private static final Logger LOGGER = LoggerFactory.getLogger(AccountServiceClientFallback.class);

@Override
public String getAccount(String accountName) {
LOGGER.error("Error during getAccount, accountName: {}", accountName);
}
}

fallbackFactory

也是容错的处理,可以知道熔断的异常信息。可以自定义​​fallbackFactory​​:

@Component
public class UserRemoteClientFallbackFactory implements FallbackFactory<UserRemoteClient> {
private Logger logger = LoggerFactory.getLogger(UserRemoteClientFallbackFactory.class);

@Override
public UserRemoteClient create(Throwable cause) {
return new UserRemoteClient() {
@Override
public User getUser(int id) {
logger.error("UserRemoteClient.getUser异常", cause);
return new User(0, "默认");
}
};
}
}

@FeignClient(value = "user-service", fallbackFactory = UserRemoteClientFallbackFactory.class)
public interface UserRemoteClient {

@GetMapping("/user/get")
public User getUser(@RequestParam("id") int id);

}

primary

​primary​​对应的是​​@Primary​​注解,默认为​​true​​,官方这样设置也是有原因的。当我们的​​Feign​​实现了​​fallback​​后,也就意味着​​FeignClient​​有多个相同的​​Bean​​在​​Spring​​容器中,当我们在使用​​@Autowired​​进行注入的时候,不知道注入哪个,所以我们需要设置一个优先级高的,​​@Primary​​注解就是干这件事情的。

qualifier

​qualifier​​对应的是​​@Qualifier​​注解,使用场景跟上面的​​primary​​关系很淡,一般场景直接@Autowired直接注入就可以了。

如果我们的​​Feign Client​​有​​fallback​​实现,默认​​@FeignClient​​注解的​​primary=true​​, 意味着我们使用​​@Autowired​​注入是没有问题的,会优先注入你的​​FeignClient​​。

如果你把​​primary​​设置成​​false​​了,直接用​​@Autowired​​注入的地方就会报错,不知道要注入哪个对象。

解决方案很明显,你可以将​​primary​​设置成​​true​​即可,如果由于某些特殊原因,你必须得去掉​​primary=true​​的设置,这种情况下我们怎么进行注入,我们可以配置一个​​qualifier​​,然后使用​​@Qualifier​​注解进行注入,示列如下:

@FeignClient(name = "optimization-user", path="user", qualifier="userRemoteClient")
public interface UserRemoteClient {

@GetMapping("/get")
public User getUser(@RequestParam("id") int id);
}

Feign Client注入

@Autowired
@Qualifier("userRemoteClient")
private UserRemoteClient userRemoteClient;

好了,以上就是@FeignClient注解相关属性说明。

标签:FeignClient,调用,String,default,user,注解,public,name
From: https://blog.51cto.com/u_15773567/5779773

相关文章

  • 【Spring第六篇】注解:Annotation
    注解:Annotation首先不惜在spring容器配置中加上以下字段:<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns......
  • php 调用c# .NET 写的webservice(亲测通过)
    先上结果图——C# 代码:usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Web;usingSystem.Web.Services;usingSystem.Web.Services......
  • Android调用华为统一扫码服务
    1.Android新建project此时注意新建的project的包名和项目名称,后面需要这2个 2.在华为开发平台新建项目并创建应用,此时需要输入项目名称和包名,要和上面的一致https......
  • SpringCloud FeignClient的坑(httpClient连接池的使用)
    SpringCloudFeignClient的坑(httpClient连接池的使用)前言在头条上已经发布过不少的文章了,根据文章的浏览量来看,go语言的市场需求明显是小于java的需求量的,最近也开始发布......
  • Springboot之@Transactional事务注解原理详解
    @Transactional注解的逻辑是通过动态代理来实现的,而生成这个动态代理类分成了两步:1、向spring容器注册事务相关的切面逻辑2、根据切面逻辑生成动态代理下面围绕这两点来看......
  • springboot 常用的注解,解决面试
    一: ComponentScan :作用扫描二: MapperScan :扫描mapper 三: @SpringBootApplication组合注解四: @EnableAutoConfiguration开启自动配置的功能五: @AutoConfigurat......
  • 对于子类的构造方法在运行之前,必须调用父类的构造方法的问题
    首先我们来了解一下什么是构造函数。构造函数是一种特殊的方法主要用来在创建对象时初始化对象,总与new运算符一起使用在创建对象的语句中,特别是一个类可以有多个构造函数的......
  • A调用B方法,@Transactional事务问题
    总结:方法A调用方法B:1、如果只有A加@Transactional注解;则AB在同一事务中,任意异常都回滚;2、如果只有B加@Transactional注解;AB方法为同一类,事务失效任意异常都不回滚;AB不同类......
  • 在JPA中调用存储过程并及时将资源释放
    问题最近发现在调用某个API执行batchjob(批处理)时,每当数据量达到一定数量时,后续的记录都会出现以下错误:oracleORA-01000:maximumopencursorsexceeded原因排查......
  • 第三方接口调用httpUtils
    1.GET请求publicstaticJSONObjectgetHttpGetResp(Stringurl,Stringauthorization,Stringtitle){HttpGethttpGet=newHttpGet(url);Stri......