纯javaBean配置 ssm 报错 No qualifying bean of type [springMybatisNoXml.RoleMapper] found for dependency

在阅读《高性能Java Persistence》一书时,作者使用纯JavaBean配置SSM,但在实践中遇到No qualifying bean of type [springMybatisNoXml.RoleMapper] found for dependency的错误。通过排查发现,Mapper Bean未成功注册。通过将日志级别设置为DEBUG,发现Spring在构建完特定bean后未继续构建RoleMapper。问题在于Mapper接口的自动扫描配置。通过查阅文档,修正了自动扫描的配置,解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

最近在重新看 <<Java EE 联网轻量级框架整合开发>>,也就是这本书,最最后一章有一个模拟高并发抢红包的案例,其中作者采用了纯 java bean 的配置方式,但是我按照作者的流程走下来,发现总是报如题的错误,但是代码和作者所写的又没有什么差别,很奇怪。在网上搜了很多博客都没有相关的错误,甚至于有些博客写的注解配置和该书作者的配置完全相同,且能够运行,我从网上下载下了博客作者的 demo,在本地运行,发现也是报同样的错误,令人非常沮丧,只好决定自己去探索一下。

探索过程

文件结构和配置文件

文件结构
在这里插入图片描述
配置文件 RootConfig

@Configuration
@ComponentScan(value="springMybatisNoXml.*", includeFilters= {@Filter(type = FilterType.ANNOTATION , value ={Repository.class})})
@EnableTransactionManagement
@MapperScan("springMybatisNoXml")
public class RootConfig  {
	private DataSource dataSource = null ;
	/*
	 * 注册数据库 Bean
	 */
	@Bean(name = "dataSource")
	public DataSource initDataSource() {
		if(dataSource != null) {
			return dataSource;
		}
		Properties props = new Properties();
		props.setProperty("driverClassName", "com.mysql.jdbc.Driver");
		props.setProperty("url", "jdbc:mysql://localhost/exierse?zeroDateTimeBehavior=convertToNull");
		props.setProperty("username", "root");
		props.setProperty("password","");
		props.setProperty("maxActive","200");
		props.setProperty("maxIdle", "2");
		props.setProperty("maxWait", "3000");
		try {
			dataSource = BasicDataSourceFactory.createDataSource(props) ;
		}catch (Exception e) {
			// TODO: handle exception
		}
		return dataSource;
	}
	
	/**
	 * 注册 sqlSessionFactory,存在问题,无法将 Mapper 注入到 bean 中
	 * @return
	 * @throws Exception 
	 */
    @Bean(name="sqlSessionFactory")
    public SqlSessionFactory  initSqlSessionFactory() throws Exception {
    	// 新建 SqlSessionFactoryBean
        SqlSessionFactoryBean sqlSessionFactory=new SqlSessionFactoryBean();
        // 设置数据源
        sqlSessionFactory.setDataSource(initDataSource());
        // 读取 Mybatis 的配置文件
        Resource resource=new ClassPathResource("springMybatisNoXml/mybatis-config.xml");
        // 引入配置
        sqlSessionFactory.setConfigLocation(resource);
        // 注入 sqlSessionFactory
        return sqlSessionFactory.getObject();
    }
    
    /**
     * mapper 扫描
     * @return
     */
    @Bean
    public MapperScannerConfigurer initMapperScannerConfigurer() {
        MapperScannerConfigurer msc=new MapperScannerConfigurer();
        msc.setBasePackage("springMybatisNoXml");
        msc.setSqlSessionFactoryBeanName("sqlSessionFactory");
        msc.setAnnotationClass(Repository.class);
        return msc;
    }
}

测试文件

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = springMybatisNoXml.RootConfig.class)
public class testDao{
	@Resource
	private RoleMapper roleMapper;
	
    @Test
    public void testDecreaseRedPacket(){
    	Role role = roleMapper.getRole(1L);
    	System.out.println("role" + role);
    }
}
mybatis + spring 运行不报错?

Mybatis 和 spring 结合之后,运行时只会报和 spring 有关的错误,比如找不到 bean,找不到 Mybatis 配置文件。
如果是找不到 Mybatis,只要检查一下文件路径是否正确,但是如果找不到 bean,就无法直接确定问题,此时我想到可以配置 log4j.properties 提高日志标准到 DEBUG 水平来查看 spring 的运行过程,配置运行之后发现 spring 完成 sqlSessionFactory 这个 bean 的构建之后就没有再去寻找并构建 RoleMapper 这些 Bean 了,说明 Mapper 接口对应的 Bean 没有注册成功。

Mapper Bean 没有注册成功

首先考虑可能是 Mapper 接口上没有用 @Repository 来修饰,检查后发现已经标注好了

@Repository
public interface RoleMapper {
	public int insertRole(Role role);
	public Role getRole(@Param("id") Long id);
	public int updateRole(Role role);
	public int deleteRole(@Param("id") Long id);
}

这就意味着配置中的 Mapper 自动扫描有问题,也就是下面

  /**
     * mapper 扫描
     * @return
     */
    @Bean
    public MapperScannerConfigurer initMapperScannerConfigurer() {
        MapperScannerConfigurer msc=new MapperScannerConfigurer();
        msc.setBasePackage("springMybatisNoXml");
        msc.setSqlSessionFactoryBeanName("sqlSessionFactory");
        msc.setAnnotationClass(Repository.class);
        return msc;
    }

RootConfig 类中使用最原始的注册方式注册 Mapper,如下所示,发现 Mapper 好用,那就是自动扫描不行。

	@Bean
	public RoleMapper userMapper() throws Exception {
	  SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(initSqlSessionFactory());
	  return sqlSessionTemplate.getMapper(RoleMapper.class);
	}

为了探寻原因,直接找到了 spring-Mybatis 的官方文档,发现自动扫描应该这样写

@Configuration
@MapperScan("org.mybatis.spring.sample.mapper") // mapper 接口的路径
public class AppConfig {
  // ...
}

之后就运行正常了

最后

找到了在纯 java Bean 下实现自动扫描 Mapper 接口的方法之后,我对作者那种写法为什么不正确也就没啥兴趣了。要想知道报错原因,我认为这可能得去了解一下 spring 和 Mybatis 的版本适配问题,但是这个就非常鸡肋了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值