@FeignClient 是 Spring Cloud 中用于声明一个 Feign 客户端的注解。Feign 是一个声明式的 Web Service 客户端,它的目的是让编写 HTTP 客户端变得更简单。通过 Feign,只需要创建一个接口,并使用注解来描述请求,就可以直接执行 HTTP 请求了。
在微服务架构中,使用FeignClient注解可以轻松实现各模块之间的调用
@FeignClient()注解只能在接口上使用,它的基本用法如下:
@FeignClient("stores")
public interface StoreClient {
@RequestMapping(method = RequestMethod.GET, value = "/stores")
List<Store> getStores();
@RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
Store update(@PathVariable("storeId") Long storeId, Store store);
}
服务的启动类要有@EnableFeignClients 注解才能使Fegin生效
name(和value相同):指定FeignClient的名称,如果项目使用了注册中心,name属性会作为微服务(注册到注册中心的名字)的名称,用于服务发现,会在注册中心查找对应名称的服务
url:FeignClient调用的地址,用于指定Feign客户端调用的地址,优先级比服务名(name)高,如果配置了url,那么将以url的路径进行请求
contextId:FeigntContext维护着客户端map的key,如果没设置,默认是name属性,如果是默认属性的话,那么一个客户端只能有一个@FeignClient接口,有时候我们不想将一个服务的所有调用接口都定义在一个接口中,那么就需要定义不同的contextId,否则启动的时候会报错(Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true)
如下所示,我们为user服务创建了两个相同服务的接口
/**
* user服务的第一个FeigntClient接口
*/
@FeignClient(name = "user",contextId="userfeignt1")
public interface UserFeigntClient1 {
@GetMapping("/user/get")
public User getUser(@RequestParam("id") int id);
}
/**
* user服务的第二个FeigntClient接口
*/
@FeignClient(name = "user",contextId="userfeignt2")
public interface UserFeigntClient2 {
@PostMapping("/user/get")
public int updateUser(User user);
}
注:contextId不能带_等符号
decode404:布尔值,默认是false,表示对于一个HTTP状态码为404的请求是否需要进行解码。默认为 false,表示不进行解码,当成一个异常处理。设置为true 之后,遇到HTTP状态码为404的Response还是会解析这个请求的body
fallback:表示fallback类,也就是容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑。需要实现FeignClient对应的接口,当调用方法发生异常时,会调用这个Fallback类对应的FeignClient接口方法。如果配置了fallback属性,就会把Fallback类包装在一个默认的FallbackFactory实现类FallbackFactory.Default上,而不使用fallbackFactory属性对应的FallbackFactory实现类。
容错类如下:
@Component
public class UserFeigntClient1Fallback implements UserFeigntClient1{
@Override
public User getUser(int id) {
return new User();
}
}
fallbackFactory:表示生产 fallback 类的Factory,需要实现feign.hystrix.FallbackFactory接口,FallbackFactory内部会针对一个Throwable异常返回一个Fallback类进行fallback操作。
fallbackFactory类可以获取异常,更推荐使用fallbackFactory来定义容错类
@Slf4j
@Component
public class UserFeigntClient1FallbackFactory implements FallbackFactory<UserFeigntClient1> {
@Override
public UserFeigntClient1 create(Throwable throwable) {
return new UserFeigntClient1() {
@Override
public User getUser(int id) {
log.error("获取账号异常:{},异常:{}",id,throwable);
return new User();
}
};
}
}
configuration:用于指定Feign配置类,通过实现FeignConfigurer接口,可以自定义Feign的Encoder、Decoder、LogLevel、Contract等属性
@FeignClient(name = "exampleClient", configuration = ExampleFeignConfig.class)
public interface ExampleClient {
// 定义示例客户端的方法
}
@Configuration
public class ExampleFeignConfig implements FeignConfigurer {
@Override
public void configure(Client.Builder clientBuilder) {
clientBuilder.encoder(new GzipEncoder());
clientBuilder.decoder(new GzipDecoder());
}
}
path:定义当前FeignClient的统一前缀,在服务名或URL与requestPath之间,它指定了Feign客户端在发送HTTP请求时需要附加的路径信息,
比如我們設置了path = “/api”,那麽Feign客户端将在发送请求时将该路径附加到URL上。例如,目标URL为http://example.com,那么实际发送的请求URL将为http://example.com/api