iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >springboot-启动bean冲突的解决
  • 301
分享到

springboot-启动bean冲突的解决

2024-04-02 19:04:59 301人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录启动bean冲突启动提示bean重复问题先说结论原理启动bean冲突 在一次启动中遇到了bean冲突的问题,提示存在两个名称重复的bean org.springframework

启动bean冲突

在一次启动中遇到了bean冲突的问题,提示存在两个名称重复的bean

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.test.api.Application]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'healthCheckController' for bean class [com.test.datahub.controller.HealthCheckController] conflicts with existing, non-compatible bean definition of same name and class [com.test.api.controller.HealthCheckController]

项目中包括多个模块,其中A、B两个模块都有同一个类:

HealthCheckController,检查更改信息发现,不知道谁在A模块添加了B模块的依赖,造成了这一问题,删除后解决

        <dependency>
            <groupId>com.test</groupId>
            <artifactId>B</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>

启动提示bean重复问题

先说结论

只需要在@FeignClient注解的contextId属性上加上独一的标示,即可解决问题

原理

是因为注册feignClient的时候会注册ClientConfiguration,参考代码如下

public void reGISterFeignClients(AnnotationMetadata metadata,
      BeanDefinitionRegistry registry) {
   //...此处省略部分代码
   //
   for (String basePackage : basePackages) {
      Set<BeanDefinition> candidateComponents = scanner
            .findCandidateComponents(basePackage);
      for (BeanDefinition candidateComponent : candidateComponents) {
         if (candidateComponent instanceof AnnotatedBeanDefinition) {
            // verify annotated class is an interface
            //...省略部分代码
 
            //这块是把注解上的所有属性封装到map上
            Map<String, Object> attributes = annotationMetadata
            .getAnnotationAttributes(
            FeignClient.class.getCanonicalName());
 
            //这两个重点方法请看下面代码块
 
            //获取该feignClient的名字(重点关注该方法)
            String name = getClientName(attributes);
 
            //此方法就是spring注入beanDefination的步骤(重点关注该方法)
            registerClientConfiguration(registry, name,
                  attributes.get("configuration"));
 
            registerFeignClient(registry, annotationMetadata, attributes);
         }
      }
   }
}

上面的两处重点方法, 请看此处

//@param client 这个map就是通过上面的注解属性转map得到的
private String getClientName(Map<String, Object> client) {
   if (client == null) {
      return null;
   }
   //如果从contextId获取到名字,那么value有值的
   String value = (String) client.get("contextId");
   //如果value有值,那么如下3个if条件都不会走,所以contextId唯一就可以做到bean不重复,
   //如果value没有值,就会取value,因为多个client的serverName都是一样的,那么就会出现重复bean
   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());
}
 
private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name,
      Object configuration) {
   BeanDefinitionBuilder builder = BeanDefinitionBuilder
         .genericBeanDefinition(FeignClientSpecification.class);
   builder.addConstructorArgValue(name);
   builder.addConstructorArgValue(configuration);
   //在这个位置,创建beanDefinition,但是他创建的名字格式可以看出,唯一改变变量就是name,这个name就是上面看到的那个方法获取的
   registry.registerBeanDefinition(
         name + "." + FeignClientSpecification.class.getSimpleName(),
         builder.getBeanDefinition());
}

以上就是feign导致的springBean重复问题的解释,仅上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: springboot-启动bean冲突的解决

本文链接: https://www.lsjlt.com/news/143745.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作