name相同问题
在使用@FeignClient的时候,发现多个@FeignClient中的name相同就无法启动,当然了,这是因为bean名称重复了,创建bean的时候报的错,但是如何解决呢?
A bean with that name has already been defined and overriding is disabled
可以配置不同的contextId来进行解决
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @FeignClient(name = "SPRINGCLOUD2-PROVIDER",contextId = "DeptClient",fallbackFactory = DeptClientFallBackFactory.class) public interface DeptClient {
@GetMapping(value = "/dept/get/{id}") CommonResult<Dept> get(@PathVariable("id") long id);
@GetMapping("/timeout") String timeout(); }
@FeignClient(name = "SPRINGCLOUD2-PROVIDER",contextId = "DeptClient1",fallbackFactory = DeptClientFallBackFactory.class) public interface DeptClient1 {
@GetMapping(value = "/dept/get/{id}") CommonResult<Dept> get(@PathVariable("id") long id);
@GetMapping("/timeout") String timeout(); }
|
为什么可以这样解决呢?
1 2 3
| String name = getClientName(attributes); registerClientConfiguration(registry, name, attributes.get("configuration"));
|
在FeignClientsRegistrar中进行@FeignClient注册时,对于bean的名称是调用getClientName(Map client)方法来获取的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| private String getClientName(Map<String, Object> client) { if (client == null) { return null; } String value = (String) client.get("contextId"); if (!StringUtils.hasText(value)) { value = (String) client.get("value"); } if (!StringUtils.hasText(value)) { value = (String) client.get("name"); } if (!StringUtils.hasText(value)) { value = (String) client.get("serviceId"); } if (StringUtils.hasText(value)) { return value; }
throw new IllegalStateException("Either 'name' or 'value' must be provided in @" + FeignClient.class.getSimpleName()); }
|
代码也比较简单,可以看到是先获取的contextId,如果配置了 contextId 就会用 contextId,如果没有配置就会取 value 然后是 name 最后是 serviceId
获取到clientName之后进行bean注册
1 2 3 4 5 6 7 8 9 10
| private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name, Object configuration) { BeanDefinitionBuilder builder = BeanDefinitionBuilder .genericBeanDefinition(FeignClientSpecification.class); builder.addConstructorArgValue(name); builder.addConstructorArgValue(configuration); registry.registerBeanDefinition( name + "." + FeignClientSpecification.class.getSimpleName(), builder.getBeanDefinition()); }
|
拼接的beanName就是clientName.FeignClientSpecification