程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-06(1)

@FeignClient注解 中属性 contextId使用

发布于2021-05-29 22:55     阅读(1218)     评论(0)     点赞(24)     收藏(0)


一、概述

如果我们使用Feign定义了两个接口,但是目标服务是同一个,那么在SpringBoot启动时就会遇到一个问题:

  1. Description:
  2. The bean 'xxxxxxxx.FeignClientSpecification', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled.
  3. Action:
  4. Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

二、解决方案

2.1 方案1

修改yml配置:spring.main.allow-bean-definition-overriding=true

  1. spring:
  2.   main:
  3.     allow-bean-definition-overriding: true

2.2 方案2

在每个Feign的接口中,在注解上加 contextId属性

contextId在Feign Client的作用是在注册Feign Client Configuration的时候需要一个名称,名称是通过getClientName方法获取的

  1. @FeignClient(name = "sale-service",contextId= "saleservice1")
  2.  
  3. public interface saleClient{
  4.  
  5.     @RequestMapping(value = "/sale/add", method = RequestMethod.GET)
  6.  
  7.     String add(@RequestParam("saleNum") String queryStr);
  8.  
  9. }

备注:contextId= "名称" 中的名称,不能用“_”会报错,可以用“-”

 三、源代码分析

包名:spring-cloud-openfeign-core-2.2.5.RELEASE.jar

类路径:org.springframework.cloud.openfeign.FeignClientsRegistrar

相关代码1:

  1. private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {
  2. String className = annotationMetadata.getClassName();
  3. BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);
  4. this.validate(attributes);
  5. definition.addPropertyValue("url", this.getUrl(attributes));
  6. definition.addPropertyValue("path", this.getPath(attributes));
  7. String name = this.getName(attributes);
  8. definition.addPropertyValue("name", name);
  9. String contextId = this.getContextId(attributes);
  10. definition.addPropertyValue("contextId", contextId);
  11. definition.addPropertyValue("type", className);
  12. definition.addPropertyValue("decode404", attributes.get("decode404"));
  13. definition.addPropertyValue("fallback", attributes.get("fallback"));
  14. definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory"));
  15. definition.setAutowireMode(2);
  16. String alias = contextId + "FeignClient";
  17. AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
  18. beanDefinition.setAttribute("factoryBeanObjectType", className);
  19. boolean primary = (Boolean)attributes.get("primary");
  20. beanDefinition.setPrimary(primary);
  21. String qualifier = this.getQualifier(attributes);
  22. if (StringUtils.hasText(qualifier)) {
  23. alias = qualifier;
  24. }
  25. BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, new String[]{alias});
  26. BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
  27. }

代码截图:

相关代码2: 

可以看到, name应该是从注解中的属性取值来的, 再看看getClientName()方法.

  1. private String getClientName(Map<String, Object> client) {
  2. if (client == null) {
  3. return null;
  4. } else {
  5. String value = (String)client.get("contextId");
  6. if (!StringUtils.hasText(value)) {
  7. value = (String)client.get("value");
  8. }
  9. if (!StringUtils.hasText(value)) {
  10. value = (String)client.get("name");
  11. }
  12. if (!StringUtils.hasText(value)) {
  13. value = (String)client.get("serviceId");
  14. }
  15. if (StringUtils.hasText(value)) {
  16. return value;
  17. } else {
  18. throw new IllegalStateException("Either 'name' or 'value' must be provided in @" + FeignClient.class.getSimpleName());
  19. }
  20. }
  21. }

代码截图:

一目了然了, 我们声明@FeignClient注解时, 只使用了value属性, 所以产生了冲突, 只要加上contextId就好了.

原文链接:https://blog.csdn.net/lazycheerup/article/details/117322269



所属网站分类: 技术文章 > 博客

作者:小泽圈儿郎

链接:http://www.javaheidong.com/blog/article/207623/bae16143ac81b9a76bf2/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

24 0
收藏该文
已收藏

评论内容:(最多支持255个字符)