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

【实践丨SpringBoot整合Mybatis-Plus项目存在Mapper时报错】会挽雕弓如满月,西北望,射天狼。这篇文章主要讲述实践丨SpringBoot整合Mybatis-Plus项目存在Mapper时报错相关的知识,希望能为你提供帮助。

?摘要:?在SpringBoot运行测试Mybatis-Plus测试的时候报错的问题分析与修复
本文分享自华为云社区《??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();


@PostConstruct
public 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
@ConditionalOnMissingBean
public 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
@ConditionalOnMissingBean
public 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()


@PostConstruct
public 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")



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

    推荐阅读