FeignClient注解被@Target(ElementType.TYPE)修饰,表示FeignClient注解的作用目标在接口上。源码如下:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FeignClient { @AliasFor("name") String value() default ""; @Deprecated String serviceId() 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; }
声明接口之后,在代码中通过@Resource注入之后即可使用。@FeignClient标签的常用属性下面将逐一详解。
从源码可以得知,name是value的别名,value也是name的别名。两者的作用是一致的,name指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现。
其中,serviceId和value的作用一样,用于指定服务ID,已经废弃。
实例:下面通过name或者value指定服务名,然后根据服务名调用hi或getDate服务。
该属性用来指定@Qualifier注解的值,该值是该FeignClient的限定词,可以使用改值进行引用。实例如下:
客户端使用“myScheualService”标识注入服务。代码如下:
url属性一般用于调试程序,允许我们手动指定@FeignClient调用的地址。实例:
上面指定服务调用的地址为https://localhost:8762
当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException。
实例:下面代码去访问一个在服务“service-hi”上面没有的服务/hi(服务实际地址为:/app/service/hi),代码如下:
调用上面的sayHiFormClientOne()方法时,Spring Boot将给出如下错误信息:
为了在调用服务抛出404错误时,返回一些有用的信息。我们可以将decode404参数设置为true。代码如下:
此时调用sayHiFromClientOne()方法时,返回如下错误信息:
设置decode404=true,需要通过设置configuration去配置decode。configuration的源码如下:
通过源码得知,默认情况下使用FeignClientsConfiguration类,其中Decoder默认使用SpringDecoder。FeignClientsConfiguration部分源代码如下:
自定义configuration查看下面章节。
Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract。
实例:自定义configuration配置类,简单的定义一个自己的Decoder,该Decoder配合decod404=true使用;当服务调用抛出404错误时,将自动调用自定义的Decoder,输出一个简单的字符串。代码如下:
(1)定义一个Controller,提供给一个REST服务/hi。如下:
(2)编写FeignClient类SchedualServiceHi7,代码如下:
(3)编写MyConfiguration配置类,代码如下:
(4)编写自定义的Decoder类MyDecoder。代码如下:
当你调用服务/hi发生404时,输出如下信息:
fallback:定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口。
fallbackFactory:工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码。
path属性定义当前FeignClient的统一前缀。这样方便在该FeignClient中的@RequestMapping中书写value值。假如存在一系列的用户管理服务,如下:
/app/service/userManager/get
/app/service/userManager/insert
/app/service/userManager/update
/app/service/userManager/delete
我们次都在@RequestMapping注解中编写全服务名称,是不是有点啰嗦。因此可以设置FeignClient的path路径为“/app/service/userManager”,简化@RequestMapping的编写。
实例:定义一个FeignClient,定义服务前缀为“/app/service”。
当我们调用sayHiFormClientOne()方法时将请求https://service-hi/app/service/hi服务。
是否将伪代理标记为主Bean,默认为true。代码如下:
项目源码: