ConflictingBeanDefinitionException类名重复问题解决

问题:项目中遇到了定义的类名相同,包名不同,springboot项目启动时报ConflictingBeanDefinitionException。

查下来问题产生的原因是bean被初始化到spring容器的时候,使用的key默认是截取类完整路径的最后一个 “.” 之后的名称,
如:java.lang.String 被截取出来的就是 String 。AnnotationBeanNameGenerator源码如下:


在这里插入图片描述
解决方案:自定义BeanNameGenerator并指定

package **;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.util.StringUtils;

public class MyBeanNameGenerator extends AnnotationBeanNameGenerator {
    @Override
    public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
        if (definition instanceof AnnotatedBeanDefinition) {
            String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
            if (StringUtils.hasText(beanName)) {
                // Explicit bean name found.
                return beanName;
            }
        }
        String beanClassName = definition.getBeanClassName();
       
        return beanClassName;
    }
}
@MapperScan(value = "com.ll.api.*.mapper", nameGenerator = MyBeanNameGenerator.class)
@SpringBootApplication
@Import({ MybatisPlusConfig.class })
@ComponentScan(basePackages = { "com.ll" }, nameGenerator = MyBeanNameGenerator.class)
public class MySpringbootApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(MySpringbootApplication.class, args);
    }
}

这里又遇到了几个坑点,一并记录下:
1、@MapperScan mybatis的扫码mapper的注解也需要指定nameGenerator为自定义的MyBeanNameGenerator;
2、@MapperScan扫描的包路径要指定到mapper文件对应的路径,别把其它类所在的包扫描进来。
我原本使用 @MapperScan(value = “com.ll”, nameGenerator = MyBeanNameGenerator.class) 就出问题了,项目启动报错:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.ll.**' available: expected single matching bean but found 2: com.ll.MyService,com.ll.IMyService

原因应该是mybatis扫描mapper文件的时候好死不死把除@Mapper注解之外的bean也给加载到spring ioc容器中了,其中就包含了我们加了@Service注解的MyService类

3、如果项目中有一个接口类拥有多个实现类,在使用@Autowired直接注入的时候会报错。spring容器无法知道我们默认要用哪个。此问题两种解法,
一是给默认要加载的实现类加上 @Primary 注解,表示有多个实现类时优先使用该类。
二是使用@Qualifier注解,先在实现类的Service注解加上ID,如@Service(“employeeService1”),然后在要使用该接口类的地方使用
@Qualifier(“employeeService”)指明实现类ID

// 实现类:
@Service("myServiceImpl1")
public class MyServiceImpl1 implements IMyService {
   
}

// 使用到的地方:
@Controller

public class MyControl {
    
    @Autowired
    @Qualifier("myServiceImpl1")
    IMyService myService;
    
    @RequestMapping( ... )
    public void doSomething(HttpServletRequest request, HttpServletResponse response {
            //#略
    }
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值