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


    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    name

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

    value

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

    serviceId

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

    contextId

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

    UserFeignClientA

    @FeignClient(name = "user.service", contextId = "userServiceA", url = "${user.service.url}", configuration = UserRemoteConfig.class)
    public interface UserFeignClientA {
    
        /**
         * 获取用户默认身份信息
         */
        @RequestMapping("/user/identity/default") 
        ResultData getDefaultIdentity(@RequestParam("userId") String userId);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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 saveIdentity(@RequestBody UserVisaIdentity userVisaIdentity);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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> search(@Valid @SpringQueryMap TemplateSearchDto templateSearchDto);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

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

    configuration

    configuration是配置Feign配置类,在配置类中可以自定义FeignEncoderDecoderLogLevelContract等。

    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); 
         } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    fallbackFactory

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

    @Component
    public class UserRemoteClientFallbackFactory implements FallbackFactory {
        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);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    primary

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

    qualifier

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

    如果我们的Feign Clientfallback实现,默认@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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Feign Client注入

    @Autowired
    @Qualifier("userRemoteClient")
    private UserRemoteClient userRemoteClient;
    
    • 1
    • 2
    • 3

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

  • 相关阅读:
    CRM系统主要包括哪些功能?
    UVA1210 连续素数之和 Sum of Consecutive Prime Numbers
    Linux内核驱动开发-001字符设备开发-内核中断驱动独立按键+等待队列优化
    多线程ThreadLocal详细介绍
    LeetCode 算法:最大子数组和c++
    Git学习笔记8
    数仓:爱奇艺数仓平台建设实践
    RocketMQ(3)之事务消息
    Python基础入门篇【37】-异常:finally关键字的使用、自定义异常类型及自定义异常抛出
    【图像处理】获取图片像素点
  • 原文地址:https://blog.csdn.net/Huangjiazhen711/article/details/127424109