MapperScannerConfigurer中报错:No qualifying bean of type ‘com....AccountDao‘ available

问题

在spring整合mybatis控制创建连接对象和加载mybatis映射配置扫描,将其作为spring的bean进行管理的过程中,无法读取到自动装配的bean。
在这里插入图片描述

原因分析

1.查看调用实体类中是否有Dao的自动注入

在这里插入图片描述

2.查看MyBatisConfig配置
public class MyBatisConfig {
   @Bean
    public SqlSessionFactoryBean getSqlSessionFactoryBean(@Autowired DataSource dataSource){
        SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
        ssfb.setTypeAliasesPackage("com.fjd.domain");
        ssfb.setDataSource(dataSource);
        return ssfb;
    }

    @Bean
    public MapperScannerConfigurer getSqlSessionFactoryBean(){
        MapperScannerConfigurer mscf = new MapperScannerConfigurer();
        mscf.setBasePackage("com.fjd.dao");
        //mscf.setSqlSessionFactoryBeanName("sqlSessionFactory");
        return mscf;
    }
}

通过观察发现,AccountDao通过Autowired自动注入了,但是在MyBatis配置的过程中getSqlSessionFactoryBean()方法命名有误,应为sqlSessionFactory

问题核心:Spring 的 Bean 命名机制

1. @Bean 方法名的双重作用
  • 创建 Bean:@Bean 方法用于创建和返回 Bean
  • 定义 Bean 名称:默认情况下,方法名就是 Bean 的名称
@Bean
public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource) {
    // 这个方法会创建一个名为 "getSqlSessionFactoryBean" 的 Bean
}
2. MapperScannerConfigurer 的依赖要求
@Bean
public MapperScannerConfigurer getMapperScannerConfigurer() {
    MapperScannerConfigurer configurer = new MapperScannerConfigurer();
    configurer.setSqlSessionFactoryBeanName("sqlSessionFactory"); // 明确指定需要名为 "sqlSessionFactory" 的 Bean
    return configurer;
}
3.命名不匹配导致的问题
  • 原始状态(失败)
组件名称问题
SqlSessionFactoryBeangetSqlSessionFactoryBean实际存在的 Bean 名称
MapperScannerConfigurer 要求sqlSessionFactory期望的 Bean 名称
结果❌ 不匹配MyBatis 无法找到所需工厂
  • 修改后(成功)
组件名称结果
SqlSessionFactoryBeansqlSessionFactory实际存在的 Bean 名称
MapperScannerConfigurer 要求sqlSessionFactory期望的 Bean 名称
结果✅ 匹配MyBatis 可以找到所需工厂
4.为什么名称如此重要?
  1. MapperScannerConfigurer 的工作原理
    当配置 MapperScannerConfigurer 时:
configurer.setSqlSessionFactoryBeanName("sqlSessionFactory");

        它会在 Spring 容器中查找名为 sqlSessionFactory 的 Bean,而不是通过类型查找。

  1. Spring 容器中的 Bean 查找机制
    按名称查找优先于按类型查找
    当明确指定名称时,Spring 只按名称查找
    如果名称不匹配,即使类型正确也会失败

解决方案

方案 1:修改方法名
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
    // 方法名与所需名称一致
}
方案 2:显式指定 Bean 名称
@Bean("sqlSessionFactory") // 显式指定名称
public SqlSessionFactoryBean anyName(DataSource dataSource) {
    // 无论方法名是什么,Bean 名称都是 "sqlSessionFactory"
}
方案 3:修改 MapperScannerConfigurer 的配置(不推荐)
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
    MapperScannerConfigurer configurer = new MapperScannerConfigurer();
    configurer.setBasePackage("com.fjd.dao");
    configurer.setSqlSessionFactoryBeanName("getSqlSessionFactoryBean"); // 匹配原始名称
    return configurer;
}

总结

  • 默认命名规则
方法名模式生成的 Bean 名称示例
getXxx()xxxgetDataSource() → dataSource
createX()createXcreateSession() → createSession
其他保持原样sqlSessionFactory() → sqlSessionFactory
  • @Bean 方法名决定了默认 Bean 名称
  • MapperScannerConfigurer 需要特定名称的 Bean
  • 两者不匹配导致 MyBatis 无法找到所需工厂
  • 修改方法名使名称一致解决了问题
  • 在 Spring 和 MyBatis 整合的项目中,虽然 DAO 接口(如 AccountDao)没有实现类,但通过 MyBatis 的动态代理机制,它仍然可以被自动装配。这是 Spring + MyBatis 整合的核心特性之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值