Feign异常--A bean with that name | HTTP method type (ex. GET, POST)


1、前置

1、这里是两个异常(别名as)
第一个异常 ‘as’ A: A bean with that name has already been defined and overriding is disabled.
第二个 ‘as’ B: Method GetFeignClient#getParameters(String,String) not annotated with HTTP method type (ex. GET, POST)
2、看了一下网上给的解决方案, 但是并没有详细的说明, 本篇文章会进行详细的解释
3、版本: Spring Cloud: Hoxton.SR3、spring-cloud-openfeign: 2.2.2.RELEASE

2、重现异常A:

@FeignClient(name = "provider")
public interface GetFeignClient {
	@RequestMapping(value = "/getNoParameters", method = RequestMethod.GET)
    CommonResult getNoParameters();
}

@FeignClient(name = "provider")
public interface PostFeignClient {
	@RequestMapping(value = "/testPost/postNoParameters", method = RequestMethod.POST)
    CommonResult postNoParameters();
}

启动项目报错: The bean ‘provider.FeignClientSpecification’ could not be registered. A bean with that name has already been defined and overriding is disabled.
在这里插入图片描述

3、重现异常B:

在重现异常B之前, 我们要先将异常A给解决掉, 就用最快捷的方式进行解决:(强烈不推荐该方式, 后面会说)

spring:
  main:
    allow-bean-definition-overriding: true
@FeignClient(name = "provider")
public interface GetFeignClient {
	@RequestMapping(value = "/getNoParameters", method = RequestMethod.GET)
    CommonResult getNoParameters();
}

@FeignClient(name = "provider", configuration = FooConfiguration.class)
public interface HeaderFeignClient {
  	@RequestLine("GET /testHeard/getHeard")
    CommonResult getHeard(@SpringQueryMap TestEntity data, @HeaderMap Map<String, Object> headerMap);
}

FooConfiguration:

package com.chaim.feignserver.config;

import feign.Contract;
import org.springframework.context.annotation.Bean;

/**
 * 详情说明见 Readme.md
 * 可以参考代码地址
 * 
 * @author Chaim
 * @date 2021/4/19 10:59
 */
//@Configurable
public class FooConfiguration {

    /**
     * 将契约改为 feign 原生的默认契约.
     * 可以使用feign自带的注解
     *
     * @return
     */
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }

关于FooConfiguration 说明:

@Configurable

feign 配置  
在 SpringCloud 中,Feign 的默认配置类是 FeignClientsConfiguration, 该类定义了 feign 默认使用的编码器、解码器、所使用的契约等.  
SpringCloud允许通过注解@FeignClient的configuration属性自定义Feign的配置 (@FeignClient(configuration= FooConfiguration.class)),  
自定义配置的优先级比FeighClientsConfiguration要高.  

可以使用 @Configurable, 声明这是一个配置类, 但此时不能将该放置在主应用程序上下文 @ComponentScan 所扫描的包中, 否则该配置将会被所有Feign Client共享,无法实现细粒度配置!  
反之, 也可以不使用 @Configurable, 从而避免父子上下文问题  

官网中有介绍(1.2): https://docs.spring.io/spring-cloud-openfeign/docs/2.2.x-SNAPSHOT/reference/html/index.html  
摘抄:   
FooConfiguration does not need to be annotated with @Configuration. However, if it is, then take care to exclude it from any @ComponentScan that would otherwise include this configuration as it will become the default source for feign.Decoder, feign.Encoder, feign.Contract, etc., when specified. This can be avoided by putting it in a separate, non-overlapping package from any @ComponentScan or @SpringBootApplication, or it can be explicitly excluded in @ComponentScan.

启动项目报错: FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Method GetFeignClient#getParameters(String,String) not annotated with HTTP method type (ex. GET, POST)
在这里插入图片描述

4、分析问题

异常A: bean名称相同, 重复的bean被定义了, 这个就不多说了

异常B: 这个就有点意思了, 他也是基于bean名称重复定义导致产生的, 简单的深入一下
1、HeaderFeignClient 指定了原生契约, 他的bean名字是provider,
2、GetFeignClient 未指定原生契约, 他的bean名字也是provider,
3、而@RequestMapping并不属于原生契约, 也就是说原生契约下不支持该注解, 就会报该error
4、那么当spring注入名称:provider引用原生契约对应的注解, 该provider都只能使用原生契约支持的注解
测试一下我们的说法:

@FeignClient(name = "provider", configuration = FooConfiguration.class)
public interface HeaderFeignClient extends HeaderService {
    @RequestLine("GET /testHeard/getHeard")
    CommonResult getHeard(@SpringQueryMap TestEntity data, @HeaderMap Map<String, Object> headerMap);

    @RequestMapping(value = "/getNoParameters", method = RequestMethod.GET)
    CommonResult getNoParameters();
}

启动项目依旧报错, 那么就验证了我们上面说的流程

5、解决方法

1、指定: contextId: 用作bean名,但不会作为服务id

@FeignClient(name = "provider", contextId = "headerProvider", configuration = FooConfiguration.class)
public interface HeaderFeignClient {
    @RequestLine("GET /testHeard/getHeard")
    CommonResult getHeard(@SpringQueryMap TestEntity data, @HeaderMap Map<String, Object> headerMap);
}

2、开启了原生契约支持, 那么就只能使用原生契约支持的注解, 不能混用
3、不到万不得已的情况下 不要用spring.main.allow-bean-definition-overriding=true用我们话说就是捏到鼻子哄眼睛

6、完结

1、简单说该问题, 如果使用@RequestLine等原生契约支持的注解, 那么就要通过configuration 配置原生契约, 并且只能使用原生契约支持的注解

2、openfeign对应的其余文章:

代码地址以及对应的postman文件
Feign的使用示列–呕心沥血之作(1)
Feign的@FeignClient详解–呕心沥血之作(2)
Feign的默认契约注解详解–呕心沥血之作(3)
Feign异常–Request method ‘POST‘ not supported
Feign异常–A bean with that name | HTTP method type (ex. GET, POST)

当在Feign调用中出现"Consider defining a bean of type 'xxx' in your configuration"的错误时,这意味着Spring容器无法找到所需的bean。 解决这个问题的方法有两种: 1. 指定Feign应该扫描的包。可以在启动类上添加`@EnableFeignClients(basePackages = "xxx")`注解,将包路径替换为你实际的包路径。这样Feign将会扫描指定的包来寻找需要的bean。 2. 指定需要加载的Client接口。在启动类上添加`@EnableFeignClients(clients = {xxx.class})`注解,将`xxx`替换为你实际的Client接口。这样Feign将会加载指定的Client接口,以便正确创建需要的bean。 通过以上两种方法之一,你可以解决Feign调用时"Consider defining a bean of type '' in your configuration"的错误。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [项目启动报错:Consider defining a bean of type ‘xxx.xx.xx.xxService‘ in your configuration.](https://blog.csdn.net/qq_43351889/article/details/123241948)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Consider defining a bean of type ‘cn.itcast.feign.clients.UserClient‘ in your configuration....](https://blog.csdn.net/weixin_43847264/article/details/126269386)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值