1、问题
今天在升级到springboot2 + spring cloud Hoxton版本之后,项目启动出现以下错误
Description:The bean 'diditech-iov-openservice.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
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
17:01:56.989 logback [main] ERROR o.s.b.d.LoggingFailureAnalysisReporter -
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'openservice.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
Disconnected from the target VM, address: '127.0.0.1:51842', transport: 'socket'
Process finished with exit code 1
2、原因
最终找到的出错原因:
由于我这个工程是封装工具用的,一个server端,多个client端。
这样的话,每个client端的@FeignClient的配置都是一样,从而导致了重名的问题
我的代码贴出来
第一个客户端:
@ConditionalOnClass(FeignClient.class)
@FeignClient("openservice")
@RequestMapping("/mail")
public interface OpenServiceMailFeignService {
}
第二个客户端
@ConditionalOnClass(FeignClient.class)
@FeignClient("openservice")
@RequestMapping("/sms")
public interface OpenServiceSmsFeignService {
}
从代码上可以看出来,两个接口的FeignClient的配置都是@FeignClient("openservice")。
3、解决方案
1、根据错误信息的提示:Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
在配置文件application.yml中添加上提示的配置即可
spring:
main:
allow-bean-definition-overriding: true
2、如果不改配置,那就需要给每个FeignClient起个别名。使用到的就是contextId属性
代码如下
第一个客户端更改后
@ConditionalOnClass(FeignClient.class)
@FeignClient("openservice", contextId = "openServiceSmsFeignService")
@RequestMapping("/sms")
public interface OpenServiceSmsFeignService {
}
第二个客户端更改后
@ConditionalOnClass(FeignClient.class)
@FeignClient("openservice", contextId = "openServiceMailFeignService")
@RequestMapping("/mail")
public interface OpenServiceMailFeignService {
}
4、备注:spring cloud 1.x重名的解决方法
以上是在spring cloud 2.x版本中的解决方法,对于spring cloud 1.x中,可是没有contextId这个属性的。
我使用下来的经验是:
1、如果不对feignclien的configuration做修改,重名的话那就重名吧,不影响调用的。
2、如果是feignclient的configuration做修改的话,可以参照我的另外的文章
(1)只对其中的一个feignclient修改,则参考:feignclient的configuration设置无效,@FeignClient的value值重复解决方案
(2)如果对多个feignclient进行修改,则参考:@FeignClient的value值重复,多个client设置不同的configuration无效的解决方案