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输出Hello World完美过程解析
Jun 13 Java/Android
java中重写父类方法加不加@Override详解
Jun 21 Java/Android
Spring Boot两种全局配置和两种注解的操作方法
Jun 29 Java/Android
mybatis中注解与xml配置的对应关系和对比分析
Aug 04 Java/Android
Java spring单点登录系统
Sep 04 Java/Android
Java设计模式之享元模式示例详解
Mar 03 Java/Android
Mybatis-Plus进阶分页与乐观锁插件及通用枚举和多数据源详解
Mar 21 Java/Android
剑指Offer之Java算法习题精讲二叉树专项训练
Mar 21 Java/Android
Java的Object类的九种方法
Apr 13 Java/Android
详解Spring Security如何在权限中使用通配符
Jun 28 Java/Android
java实现web实时消息推送的七种方案
Jul 23 Java/Android
Springboot集成kafka高级应用实战分享
Aug 14 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时间计算相关问题小结
2016/05/09 PHP
javascript 字符串连接的性能问题(多浏览器)
2008/11/18 Javascript
JS定义网页表单提交(submit)的方法
2015/03/20 Javascript
JS+CSS实现的竖向简洁折叠菜单效果代码
2015/10/22 Javascript
基于javascript实现checkbox复选框实例代码
2016/01/28 Javascript
AngularJS基础 ng-keypress 指令简单示例
2016/08/02 Javascript
基于chosen插件实现人员选择树搜索自动筛选功能
2016/09/24 Javascript
JQuery统计input和textarea文字输入数量(代码分享)
2016/12/29 Javascript
原生JS实现圆环拖拽效果
2017/04/07 Javascript
JS继承与闭包及JS实现继承的三种方式
2017/10/15 Javascript
vue中引用swiper轮播插件的教程详解
2018/08/16 Javascript
详解@Vue/Cli 3 Invalid Host header 错误解决办法
2019/01/02 Javascript
JS+CSS3实现的简易钟表效果示例
2019/04/13 Javascript
vue组件开发之tab切换组件使用详解
2020/08/21 Javascript
[08:54]《一刀刀一天》之DOTA全时刻18:十九支奔赴西雅图队伍全部出炉
2014/06/04 DOTA
[45:34]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.18
2020/12/19 DOTA
Python程序设计入门(1)基本语法简介
2014/06/13 Python
利用Python将时间或时间间隔转为ISO 8601格式方法示例
2017/09/05 Python
python中redis查看剩余过期时间及用正则通配符批量删除key的方法
2018/07/30 Python
小白入门篇使用Python搭建点击率预估模型
2018/10/12 Python
Python设计模式之简单工厂模式实例详解
2019/01/22 Python
python快排算法详解
2019/03/04 Python
解决django后台样式丢失,css资源加载失败的问题
2019/06/11 Python
Pandas之ReIndex重新索引的实现
2019/06/25 Python
Python 导入文件过程图解
2019/10/15 Python
Python网络编程之使用TCP方式传输文件操作示例
2019/11/01 Python
基于Tensorflow使用CPU而不用GPU问题的解决
2020/02/07 Python
Python-for循环的内部机制
2020/06/12 Python
Python2与Python3关于字符串编码处理的差别总结
2020/09/07 Python
python两种获取剪贴板内容的方法
2020/11/06 Python
Canvas与图片压缩的示例代码
2017/11/28 HTML / CSS
异常和异常类的概念
2014/09/12 面试题
酒店门卫岗位职责
2013/12/29 职场文书
团队经理竞聘书
2014/03/31 职场文书
Pycharm 如何设置HTML文件自动补全代码或标签
2021/05/21 Python
vue报错function () { [native code] },无法出现我们想要的内容 Unknown custom element
2022/04/11 Vue.js