本文分享自华为云社区《SpringBoot整合MybatisPlus项目存在Mapper时运行报错的问题分析与修复》,作者:攻城狮Chova 。

异常信息

  • 在SpringBoot运行测试Mybatis-Plus测试的时候报错:
rg.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.oxford.test.ApplicationTests':

原因

  • 自定义的mapper文件不受Spring管理所以不会注入到Spring容器中
  • mybatis-config中只是会为对应的mapper创建代理类
  • 想真正包装成bean, 注入到spring容器中,需要使用到AutoConfiguredMapperScannerRegistrar它会根据扫描 @Mapper注释或是 @MapperScan指定的包下的接口,将其注册为bean

  • AutoConfiguredMapperScannerRegistrar:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//package com.baomidou.mybatisplus.spring.boot.starter;import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.MybatisXMLLanguageDriver;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import java.util.Iterator;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.mapper.ClassPathMapperScanner;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;@Configuration
@ConditionalOnClass({SqlSessionFactory.class, MybatisSqlSessionFactoryBean.class})
@ConditionalOnBean({DataSource.class})
@EnableConfigurationProperties({MybatisPlusProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
public class MybatisPlusAutoConfiguration {private static final Log logger = LogFactory.getLog(MybatisPlusAutoConfiguration.class);private final MybatisPlusProperties properties;private final Interceptor[] interceptors;private final ResourceLoader resourceLoader;private final DatabaseIdProvider databaseIdProvider;private final List<ConfigurationCustomizer> configurationCustomizers;public MybatisPlusAutoConfiguration(MybatisPlusProperties properties, ObjectProvider<Interceptor[]> interceptorsProvider, ResourceLoader resourceLoader, ObjectProvider<DatabaseIdProvider> databaseIdProvider, ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider) {this.properties = properties;this.interceptors = (Interceptor[])interceptorsProvider.getIfAvailable();this.resourceLoader = resourceLoader;this.databaseIdProvider = (DatabaseIdProvider)databaseIdProvider.getIfAvailable();this.configurationCustomizers = (List)configurationCustomizersProvider.getIfAvailable();}@PostConstructpublic void checkConfigFileExists() {if (this.properties.isCheckConfigLocation() && StringUtils.hasText(this.properties.getConfigLocation())) {Resource resource = this.resourceLoader.getResource(this.properties.getConfigLocation());Assert.state(resource.exists(), "Cannot find config location: " + resource + " (please add config file or check your Mybatis configuration)");}}@Bean@ConditionalOnMissingBeanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();factory.setDataSource(dataSource);factory.setVfs(SpringBootVFS.class);if (StringUtils.hasText(this.properties.getConfigLocation())) {factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));}MybatisConfiguration configuration = this.properties.getConfiguration();if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) {configuration = new MybatisConfiguration();}if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) {Iterator i$ = this.configurationCustomizers.iterator();while(i$.hasNext()) {ConfigurationCustomizer customizer = (ConfigurationCustomizer)i$.next();customizer.customize(configuration);}}configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);factory.setConfiguration(configuration);if (this.properties.getConfigurationProperties() != null) {factory.setConfigurationProperties(this.properties.getConfigurationProperties());}if (!ObjectUtils.isEmpty(this.interceptors)) {factory.setPlugins(this.interceptors);}if (this.databaseIdProvider != null) {factory.setDatabaseIdProvider(this.databaseIdProvider);}if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());}if (StringUtils.hasLength(this.properties.getTypeEnumsPackage())) {factory.setTypeEnumsPackage(this.properties.getTypeEnumsPackage());}if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());}if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {factory.setMapperLocations(this.properties.resolveMapperLocations());}if (!ObjectUtils.isEmpty(this.properties.getGlobalConfig())) {factory.setGlobalConfig(this.properties.getGlobalConfig().convertGlobalConfiguration());}return factory.getObject();}@Bean@ConditionalOnMissingBeanpublic SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {ExecutorType executorType = this.properties.getExecutorType();return executorType != null ? new SqlSessionTemplate(sqlSessionFactory, executorType) : new SqlSessionTemplate(sqlSessionFactory);}@Configuration@Import({MybatisPlusAutoConfiguration.AutoConfiguredMapperScannerRegistrar.class})@ConditionalOnMissingBean({MapperFactoryBean.class})public static class MapperScannerRegistrarNotFoundConfiguration {public MapperScannerRegistrarNotFoundConfiguration() {}@PostConstructpublic void afterPropertiesSet() {MybatisPlusAutoConfiguration.logger.debug("No " + MapperFactoryBean.class.getName() + " found.");}}public static class AutoConfiguredMapperScannerRegistrar implements BeanFactoryAware, ImportBeanDefinitionRegistrar, ResourceLoaderAware {private BeanFactory beanFactory;private ResourceLoader resourceLoader;public AutoConfiguredMapperScannerRegistrar() {}public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {MybatisPlusAutoConfiguration.logger.debug("Searching for mappers annotated with @Mapper");ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);try {if (this.resourceLoader != null) {scanner.setResourceLoader(this.resourceLoader);}List<String> packages = AutoConfigurationPackages.get(this.beanFactory);if (MybatisPlusAutoConfiguration.logger.isDebugEnabled()) {Iterator i$ = packages.iterator();while(i$.hasNext()) {String pkg = (String)i$.next();MybatisPlusAutoConfiguration.logger.debug("Using auto-configuration base package '" + pkg + "'");}}scanner.setAnnotationClass(Mapper.class);scanner.registerFilters();scanner.doScan(StringUtils.toStringArray(packages));} catch (IllegalStateException var7) {MybatisPlusAutoConfiguration.logger.debug("Could not determine auto-configuration package, automatic mapper scanning disabled." + var7);}}public void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}public void setResourceLoader(ResourceLoader resourceLoader) {this.resourceLoader = resourceLoader;}}
}

解决办法

@Mapper

  • mapper文件的类上添加 @Mapper注解

@MapperScan

  • 在主类上添加 @MapperScan注解,指定mapper的扫描范围,注意值为mapper文件所在的包名
@MapperScan("com.oxford.mapper")

点击关注,第一时间了解华为云新鲜技术~​

实践丨SpringBoot整合Mybatis-Plus项目存在Mapper时报错相关推荐

  1. SpringBoot整合Mybatis(高级)

    SpringBoot整合Mybatis(高级) 文章目录 SpringBoot整合Mybatis(高级) 前言 基础环境配置 增删改查 ResultMap 复杂查询 多对一 一对多 动态SQL if ...

  2. SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例(转)...

    SpringBoot整合mybatis.shiro.redis实现基于数据库的细粒度动态权限管理系统实例 shiro 目录(?)[+] 前言 表结构 maven配置 配置Druid 配置mybatis ...

  3. SpringBoot整合Mybatis超详细流程

    SpringBoot整合Mybatis超详细流程 文章目录 SpringBoot整合Mybatis超详细流程 前言 详细流程 0.引入Mybatis 1.创建数据 2.创建程序目录 3.理解后台访问流 ...

  4. (一)SpringBoot 整合 MyBatis

    一.工具 IDE:idea.DB:mysql 二.创建SpringBoot工程 在Idea中使用SpringInitializr模板创建SpringBoot工程,依赖选择如下: 这里也可以不选JDBC ...

  5. springboot 整合mybatis实现curd

    springboot 整合mybatis pom文件 mvc 架构 application.properties 扩展配置,druid配置类 项目地址: https://github.com/seve ...

  6. springboot整合mysql5.7_详解SpringBoot整合MyBatis详细教程

    1. 导入依赖 首先新建一个springboot项目,勾选组件时勾选Spring Web.JDBC API.MySQL Driver 然后导入以下整合依赖 org.mybatis.spring.boo ...

  7. springboot整合mybatis 使用HikariCP连接池

    springboot整合mybatis 使用HikariCP连接池 前言 Springboot让Java开发更加美好,本节主要讲的是使用Hikari数据库连接池,如果需要使用druid连接池的请看我另 ...

  8. SpringBoot整合MyBatis并实现简单的查询功能

    学了SpringBoot整合MyBatis才知道什么叫做省事,想当初用SSM的时候,那配置是真的多,SpringBoot真的是太友好了,到底有多好,接下来演示一个对数据库的查询功能,然初学者的我们大开 ...

  9. springboot 整合mybatis plus

    简单介绍下 mybatis plus,mybatis plus(简称 MP)是一个 mybatis  的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生. 本文讲解使用 ...

最新文章

  1. selenium3浏览器驱动安装设置方法
  2. css实现图片自适应容器的几种方式
  3. uvalive4744(数论)
  4. 商品评价 - 实现分页
  5. redis存储新闻列表_Redis对象——集合(Set)
  6. 手动创建线程池 效果会更好_创建更好的,可访问的焦点效果
  7. cacheinterceptor第二次访问没被调用_访问者设计模式在OSG中的应用
  8. 【新年礼物】阿里资深p8教你学习Web全栈架构师!
  9. Git的安装与使用教程
  10. python中‘/’和‘//’区别
  11. Linux下启动Oracle数据库
  12. ssm框架返回html,ssm框架controller层返回json格式数据到页面
  13. now is all
  14. 将字符'0'-'9'转换为数字(c语言)
  15. QT的Q3DScatter使用(三维可视图)
  16. 【笔记】运营如何追求极致--混沌大学(抖音分享)
  17. 3 万亿美元,苹果问鼎全球市值最高公司宝座
  18. 第 46 届 ICPC 国际大学生程序设计竞赛亚洲区域赛(沈阳)
  19. 以太坊 day (6) 简单众筹项目的演示
  20. 9.Java SE 集合

热门文章

  1. 被坑了 | 那个写公众号,开网店的小小,被花式坑了!
  2. Bootstrap3 Font Awesome 字体图标带边框的图标
  3. 给网页穿上Word马甲
  4. CSS3 盒阴影 box-shadow属性
  5. zabbix 自动发现规则 触发器_运维监控实战篇,zabbix自动发现和自动注册图文详解...
  6. Git笔记(21) 分布式工作流程
  7. 万有引力的意思_万有引力和引力有什么不同?四种基本性质力中电磁力最多
  8. React Native 开发豆瓣评分(六)添加字体图标
  9. ASP.NET页面之间传值的方式之Cookie(个人整理)
  10. jsp内置对象的提交方式