Spring Cloud 中@FeignClient注解中的contextId屬性詳解
@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來實現(xiàn)接口的調用,不想將所有的調用接口都定義在一個接口類中,因此構建了下述兩個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配置文件中新增下述配置,允許出現(xiàn)beanName一樣的BeanDefinition
spring:
main:
allow-bean-definition-overriding: true
解決方法二
為每個FeignClient手動指定不同的contextId,contextId的作用是用來區(qū)分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注解及參數(shù)問題
在用分布式架構SpringBoot的SpringCloud技術開發(fā)過程中,@FeignClient 是一個常用的注解,且很重要的功能。它是Feign客戶端提供負載均衡的熱插拔注解,通過該注解可以動態(tài)代理創(chuàng)建Feign客戶端。
簡單理解就是,分布式架構服務之間,各子模塊系統(tǒng)內部通信的核心。
一般在一個系統(tǒng)調用另一個系統(tǒng)的接口時使用,如下:
注解
@FeignClient("XXX")
public interface XX{
....
}
該注解一般創(chuàng)建在 interface 接口中,然后在業(yè)務類@Autowired進去使用非常簡單方便。
問題背景
創(chuàng)建好interface接口后,當然要把調用該服務的接口方法定義出來,該方法對應本FeignClient的controller接口,必須重寫該接口方法(返回對象,參數(shù)值完全一樣)。
啟動項目出現(xiàn)如下報錯時,咋一看以為是在業(yè)務類中調用該接口方法時,傳參為空null而報錯。
FactoryBean threw exception on object creation; nested exception is
java.lang.IllegalStateException: RequestParam.value() was empty on parameter 0
當把傳參用數(shù)據(jù)代替時,重新啟動時;任然報如上錯誤。
貼一個報錯全截圖
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") 接口類中,檢查每個方法的參數(shù)定義時:
是否有如下情形
@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
這個參數(shù)少了個value = "XXCode", 這個是Spring 4.0版本后,@RequestParam 注解對參數(shù)傳值有了很好的封裝特性并嚴格校驗。
改為:
@RequestParam(value = "XXCode", required = false) String XXCode
之后,問題完美解決;重啟項目正常。
另外,插一句:當在項目多個地方調用同一個@FeignClien("XX")某項目時,在多個包中創(chuàng)建接口,并無影響。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Spring Security 將用戶數(shù)據(jù)存入數(shù)據(jù)庫
這篇文章主要介紹了Spring Security 如何將用戶數(shù)據(jù)存入數(shù)據(jù)庫,幫助大家更好的理解和學習Spring Security,感興趣的朋友可以了解下2020-09-09
springboot+vue2+elementui實現(xiàn)時間段查詢方法
這篇文章主要介紹了springboot+vue2+elementui實現(xiàn)時間段查詢方法,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-05-05
Mybatis-Plus使用saveOrUpdate及問題解決方法
本文主要介紹了Mybatis-Plus使用saveOrUpdate及問題解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-01-01
SpringBoot整合Mybatis與thymleft實現(xiàn)增刪改查功能詳解
MybatisPlus是國產(chǎn)的第三方插件,?它封裝了許多常用的CURDapi,免去了我們寫mapper.xml的重復勞動。本文將整合MybatisPlus實現(xiàn)增刪改查功能,感興趣的可以了解一下2022-12-12
SpringCloud Gateway的基本入門和注意點詳解
這篇文章主要介紹了SpringCloud Gateway的基本入門和注意點,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10

