name相同问题
OpenFeign 中 @FeignClient 名称冲突问题:contextId 的解决方案
在使用 OpenFeign 时,若多个@FeignClient接口的name(或value)属性相同,会导致 Spring 容器中 Bean 名称冲突,启动时报错:A bean with that name has already been defined and overriding is disabled。通过contextId属性可解决这一问题,本文将详细解析其原理和用法。
问题根源:Bean 名称生成规则
OpenFeign 在注册@FeignClient接口的配置 Bean 时,会根据特定规则生成 Bean 名称。核心逻辑在FeignClientsRegistrar类中,具体步骤如下:
获取客户端标识(clientName)
调用getClientName(Map<String, Object> client)方法生成唯一标识,优先级为:contextId > value > name > serviceId
即:若配置了contextId则优先使用,否则依次 fallback 到value、name、serviceId。// FeignClientsRegistrar.getClientName() 核心逻辑 private String getClientName(Map<String, Object> client) { String value = (String) client.get("contextId"); // 优先取contextId if (!StringUtils.hasText(value)) { value = (String) client.get("value"); // 其次取value } if (!StringUtils.hasText(value)) { value = (String) client.get("name"); // 再取name } if (!StringUtils.hasText(value)) { value = (String) client.get("serviceId"); // 最后取serviceId(已废弃) } // ... 校验逻辑 return value; }注册配置 Bean
生成的clientName会作为 Bean 名称的前缀,拼接固定后缀FeignClientSpecification,最终注册到 Spring 容器:
