注解简介
Spring Cloud Feign 是基于 Netflix feign 实现,整合了 Spring Cloud Ribbon 和 Spring Cloud Hystrix,能够轻松实现熔断器模型,提供了更高层次的封装来整合这两个基础工具以简化开发。除了提供这两者的强大功能外,还提供了一种声明式的 Web 服务客户端定义的方式,它简化了HTTP客户端的开发,使编写Web服务的客户端变得更容易。它是一个声明式的 HTTP客户端,使用Spring Cloud OpenFeign,只需要创建一个接口并注解,就能很容易地调用各服务提供的HTTP接口。
注解详解
@Target({ElementType.TYPE}) // 表示FeignClient注解的作用目标在接口上。
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface FeignClient {
// name是value是互为别名,两者的作用是一致的,name用于指定服务提供方的服务名。
// 如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现。
@AliasFor("name")
String value() default "";
/** @deprecated */
// 已废弃
@Deprecated
String serviceId() default "";
// 给每个FeignClient指定contextId,避免Bean名称冲突。
String contextId() default "";
@AliasFor("value")
String name() default "";
String qualifier() default "";
// 一般用于调试,可以手动指定@FeignClient调用的地址
String url() default "";
// 当发生404错误时,如果该字段为true会调用decoder进行解码,否则抛出FeignException
boolean decode404() default false;
// Feign的配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
Class<?>[] configuration() default {};
// 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,
// 因此fallback指定的类必须实现@FeignClient标记的接口。
/**
* @Component
* public class UserRemoteClientFallback implements UserRemoteClient {
* @Override
* public User getUser(int id) {
* return new User(0, "默认fallback");
* }
* }
*
* //用户服务
* @FeignClient(value = "user", fallback = UserRemoteClientFallback.class)
* public interface UserRemoteClient {
* @GetMapping("/user/get")
* public User getUser(@RequestParam("id")int id);
* }
*
*/
Class<?> fallback() default void.class;
/**
* @Component
* public class RemoteServicexCategoryFallbackFactory implements FallbackFactory<RemoteServicexCategoryService> {
* private static final Logger log = LoggerFactory.getLogger(RemoteServicexCategoryFallbackFactory.class);
*
* @Override
* public RemoteServicexCategoryService create(Throwable throwable) {
* log.error("类目服务调用失败:{}", throwable.getMessage());
* return new RemoteServicexCategoryService() {
* @Override
* public R<SysCategory> getCategoryById(Long categoryId) {
* return R.fail("获取类目对象失败:" + throwable.getMessage());
* }
*
* @Override
* public R<List<SysCategory>> list(SysCategory category) {
* return R.fail("获取类目列表失败:" + throwable.getMessage());
* }
* };
* }
* }
*
*/
// 工厂类,用于生成fallback类实例,通过这个属性可以实现每个接口通用的容错逻辑,减少重复的代码
Class<?> fallbackFactory() default void.class;
// 定义当前FeignClient的统一前缀,用于简化@RequestMapping的编写。
// 如果地址是/user/get, 定义了前缀是user, 那么具体方法上的路径就只需要写/get即可。
String path() default "";
/**
* primary对应的是@Primary注解,默认为true.
* 当我们的Feign实现了fallback后,也就意味着FeignClient有多个相同的Bean在Spring容器中,
* 当我们在使用@Autowired进行注入的时候,不知道注入哪个,所以我们需要设置一个优先级高的,
* @Primary注解就是干这件事情的。
*/
boolean primary() default true;
}
自定义配置
OpenFeign提供了默认的配置类FeignclientsConfiguration,该类使用了默认的编码器( encoder )、解码器( decoder )、合约( contract)等。因为OpenFeign 的核心是HTTP客户端,HTTP传输是通过数据包(流)进行的,所以在发送请求、接受响应的过程中,需要对数据进行编码和解码。OpenFeign默认使用的合约是SpringMvcContrace,它表示OpenFeign可以使用Spring MVC的注解@RequestMapping。Spring Cloud OpenFeign 允许通过@Feignclient注解的configuration属性配置自定义的配置,自定义配置会覆盖默认的配置。
常见应用架构
OpenFeign的Spring应用架构一般分为三部分:注册中心、服务提供者、服务调用者。
服务提供者向服务注册中心注册自己,然后服务调用者通过OpenFeign发送请求时,OpenFeign会向服务注册中心获取关于服务提供者的信息,然后再向服务提供者发送网络请求。
调用者添加@EnableFeignClients开启Spring Cloud OpenFeign 的自动化配置功能,只有使用了该注解,OpenFeign相关的组件和配置机制才会生效。