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


Posted in Java/Android onSeptember 25, 2021

@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")某项目时,在多个包中创建接口,并无影响。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Java/Android 相关文章推荐
Java实现简易的分词器功能
Jun 15 Java/Android
mybatis 获取无数据的字段不显示的问题
Jul 15 Java/Android
关于springboot 配置date字段返回时间戳的问题
Jul 25 Java/Android
spring boot中nativeQuery的用法
Jul 26 Java/Android
SpringBoot中HttpSessionListener的简单使用方式
Mar 17 Java/Android
SpringBoot2零基础到精通之异常处理与web原生组件注入
Mar 22 Java/Android
Java中的继承、多态以及封装
Apr 11 Java/Android
Android在Sqlite3中的应用及多线程使用数据库的建议
Apr 24 Java/Android
Spring Data JPA框架Repository自定义实现
Apr 28 Java/Android
Jmerte 分布式压测及分布式压测配置
Apr 30 Java/Android
Android Studio实现带三角函数对数运算功能的高级计算器
May 20 Java/Android
Spring中bean集合注入的方法详解
Jul 07 Java/Android
关于springboot配置druid数据源不生效问题(踩坑记)
Sep 25 #Java/Android
Java使用Unsafe类的示例详解
Sep 25 #Java/Android
Spring-cloud Config Server的3种配置方式
Sep 25 #Java/Android
MyBatis-Plus 批量插入数据的操作方法
Sep 25 #Java/Android
spring cloud 配置中心native配置方式
Sep 25 #Java/Android
spring cloud 配置中心客户端启动遇到的问题
Sep 25 #Java/Android
SpringBoot+Vue+JWT的前后端分离登录认证详细步骤
Sep 25 #Java/Android
You might like
php+js实现裁剪任意形状图片
2018/10/31 PHP
Laravel框架定时任务2种实现方式示例
2018/12/08 PHP
jQuery控制输入框只能输入数值的小例子
2013/03/20 Javascript
js判断客户端是iOS还是Android等移动终端的方法
2013/12/11 Javascript
JQuery处理json与ajax返回JSON实例代码
2014/01/03 Javascript
JavaScript 作用域链解析
2014/11/13 Javascript
JavaScript中的对象的extensible属性介绍
2014/12/30 Javascript
Node.js实现Excel转JSON
2015/04/24 Javascript
jquery操作angularjs对象
2015/06/26 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
2016/09/17 Javascript
在 Angular 中实现搜索关键字高亮示例
2017/03/21 Javascript
EasyUI中的dataGrid的行内编辑
2017/06/22 Javascript
JS实现发送短信验证后按钮倒计时功能(防止刷新倒计时失效)
2017/07/07 Javascript
浅谈node模块与npm包管理工具
2018/01/03 Javascript
JavaScript实现百度搜索框效果
2020/03/26 Javascript
vue.js内置组件之keep-alive组件使用
2018/07/10 Javascript
如何使用 vue + d3 画一棵树
2018/12/03 Javascript
利用Angular2的Observables实现交互控制的方法
2018/12/27 Javascript
vue+elementUI实现图片上传功能
2019/08/20 Javascript
js Math数学简单使用操作示例
2020/03/13 Javascript
详解Webpack4多页应用打包方案
2020/07/16 Javascript
vue 解决setTimeOut和setInterval函数无效报错的问题
2020/07/30 Javascript
jquery实现抽奖功能
2020/10/22 jQuery
深入讨论Python函数的参数的默认值所引发的问题的原因
2015/03/30 Python
详解在Python程序中自定义异常的方法
2015/10/16 Python
python 实现数字字符串左侧补零的方法
2018/12/04 Python
Python正则表达式匹配和提取IP地址
2019/06/06 Python
python 类的继承 实例方法.静态方法.类方法的代码解析
2019/08/23 Python
css3 按钮样式简单可扩展创建
2013/03/18 HTML / CSS
CSS实现限制字数功能当对象内文本溢出时显示省略标记
2014/08/20 HTML / CSS
购买澳大利亚最好的服装和内衣在线:BONDS
2016/10/14 全球购物
微博营销计划书
2014/01/10 职场文书
税务会计岗位职责
2014/02/18 职场文书
义和团口号
2014/06/17 职场文书
机械电子工程专业求职信
2014/06/22 职场文书
2014年保管员工作总结
2014/11/18 职场文书