Spring Cloud 中@FeignClient注解中的contextId属性详解

 更新时间:2021年9月25日 12:00  点击:4655

@FeignClient注解中的contextId属性

在使用@FeignClient注解前,我们需要先引入其相关依赖,版本为3.0.1

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>3.0.1</version>
</dependency>

例如我们有一个user服务,user服务中有很多个接口,我们通过@FeignClient来实现接口的调用,不想将所有的调用接口都定义在一个接口类中,因此构建了下述两个Feign接口类:

@FeignClient(name = "user-server")
public interface UserServerClient1 {
 @GetMapping("/user/get")
 public User getUser(@RequestParam("id") int id);
}
@FeignClient(name = "user-server")
public interface UserServerClient2 {
 @GetMapping("/user/getAll")
 public List<User> getAllUser();
}

这种情况下启动项目,项目就会报错,因为Bean的名称冲突了,具体错误如下:

Description:

The bean 'user-server.FeignClientSpecification' could not be registered. A bean with that name has already been defined and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

解决方法一

在yml配置文件中新增下述配置,允许出现beanName一样的BeanDefinition

spring:
  main:
    allow-bean-definition-overriding: true

解决方法二

为每个FeignClient手动指定不同的contextId,contextId的作用是用来区分FeignClient实例

@FeignClient(contextId = "userService1",name = "user-server")
public interface UserServerClient1 {
 @GetMapping("/user/get")
 public User getUser(@RequestParam("id") int id);
}
@FeignClient(contextId = "userService1",name = "user-server")
public interface UserServerClient2 {
 @GetMapping("/user/getAll")
 public List<User> getAllUser();
}

FeignClient注解及参数问题

在用分布式架构SpringBoot的SpringCloud技术开发过程中,@FeignClient 是一个常用的注解,且很重要的功能。它是Feign客户端提供负载均衡的热插拔注解,通过该注解可以动态代理创建Feign客户端。

简单理解就是,分布式架构服务之间,各子模块系统内部通信的核心。

一般在一个系统调用另一个系统的接口时使用,如下:

注解

@FeignClient("XXX")
public interface XX{
   ....
}

该注解一般创建在 interface 接口中,然后在业务类@Autowired进去使用非常简单方便。

问题背景

创建好interface接口后,当然要把调用该服务的接口方法定义出来,该方法对应本FeignClient的controller接口,必须重写该接口方法(返回对象,参数值完全一样)。

启动项目出现如下报错时,咋一看以为是在业务类中调用该接口方法时,传参为空null而报错。

FactoryBean threw exception on object creation; nested exception is

java.lang.IllegalStateException: RequestParam.value() was empty on parameter 0

当把传参用数据代替时,重新启动时;任然报如上错误。

贴一个报错全截图

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'withdrawCountRecordController': Unsatisfied dependency expressed through field 'withdrawCountService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'withdrawCountServiceImpl': Unsatisfied dependency expressed through field 'cumClient'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.epaylinks.efps.pas.clr.client.CumClient': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: RequestParam.value() was empty on parameter 0 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)

解决办法

在@FeignClien("XX") 接口类中,检查每个方法的参数定义时:

是否有如下情形

@RequestMapping(value="/XXX/query", method = RequestMethod.GET)
    public PageResult<XXutionResp> query(@RequestParam(required = false) String XXCode,
                                             @RequestParam(value = "XXnName",required = false) String institutionName,
                                             @RequestParam(value = "startTime",required = false) String startTime,

问题就在这里:

@RequestParam(required = false) String XXCode

这个参数少了个value = "XXCode", 这个是Spring 4.0版本后,@RequestParam 注解对参数传值有了很好的封装特性并严格校验。

改为:

@RequestParam(value = "XXCode", required = false) String XXCode

之后,问题完美解决;重启项目正常。

另外,插一句:当在项目多个地方调用同一个@FeignClien("XX")某项目时,在多个包中创建接口,并无影响。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。

[!--infotagslink--]

相关文章

  • 基于springcloud异步线程池、高并发请求feign的解决方案

    这篇文章主要介绍了基于springcloud异步线程池、高并发请求feign的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-25
  • Spring AOP 对象内部方法间的嵌套调用方式

    这篇文章主要介绍了Spring AOP 对象内部方法间的嵌套调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-29
  • Spring Cloud 中@FeignClient注解中的contextId属性详解

    这篇文章主要介绍了Spring Cloud 中@FeignClient注解中的contextId属性详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-25
  • Springboot如何实现Web系统License授权认证

    这篇文章主要介绍了Springboot如何实现Web系统License授权认证,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-28
  • 完美解决SpringCloud-OpenFeign使用okhttp替换不生效问题

    这篇文章主要介绍了完美解决SpringCloud-OpenFeign使用okhttp替换不生效问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-25
  • 如何在Spring WebFlux的任何地方获取Request对象

    这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下...2021-01-26
  • 详解SpringCloudGateway内存泄漏问题

    这篇文章主要介绍了详解SpringCloudGateway内存泄漏问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-16
  • Spring为什么不推荐使用@Autowired注解详析

    @Autowired 注解的主要功能就是完成自动注入,使用也非常简单,但这篇文章主要给大家介绍了关于Spring为什么不推荐使用@Autowired注解的相关资料,需要的朋友可以参考下...2021-11-03
  • Springboot如何使用mybatis实现拦截SQL分页

    这篇文章主要介绍了Springboot使用mybatis实现拦截SQL分页,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-19
  • 如何解决springcloud feign 首次调用100%失败的问题

    这篇文章主要介绍了如何解决springcloud feign 首次调用100%失败的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-23
  • SpringMVC文件上传原理及实现过程解析

    这篇文章主要介绍了SpringMVC文件上传原理及实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-07-15
  • Spring Data JPA 关键字Exists的用法说明

    这篇文章主要介绍了Spring Data JPA 关键字Exists的用法说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-10
  • spring cloud gateway中如何读取请求参数

    这篇文章主要介绍了spring cloud gateway中如何读取请求参数的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-15
  • tomcat启动完成执行 某个方法 定时任务(Spring)操作

    这篇文章主要介绍了tomcat启动完成执行 某个方法 定时任务(Spring)操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-25
  • 使用Maven 搭建 Spring MVC 本地部署Tomcat的详细教程

    这篇文章主要介绍了使用Maven 搭建 Spring MVC 本地部署Tomcat,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-16
  • Java Spring Cloud 负载均衡详解

    这篇文章主要介绍了Spring Cloud负载均衡及远程调用实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2021-09-18
  • SpringMvc自动装箱及GET请求参数原理解析

    这篇文章主要介绍了SpringMvc自动装箱及GET请求参数原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-19
  • Springboot使用thymeleaf动态模板实现刷新

    这篇文章主要介绍了Springboot使用thymeleaf动态模板实现刷新,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-08-31
  • SpringMvc获取请求头请求体消息过程解析

    这篇文章主要介绍了SpringMvc获取请求头请求体消息过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-17
  • 解决SpringCloud Feign传对象参数调用失败的问题

    这篇文章主要介绍了解决SpringCloud Feign传对象参数调用失败的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-24