NOTE
MyBatis Auto-Configuration
How Spring Boot enables MyBatis auto-configuration and how AutoConfiguredMapperScannerRegistrar determines which package to scan for @Mapper interfaces.
This is a historical learning note and may contain outdated or incomplete understanding.
1. Enable MyBatis Auto-Configuration
Spring Boot auto-configures MyBatis through MybatisAutoConfiguration, as follows:
@org.springframework.context.annotation.Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration implements InitializingBean {
@Override
public void afterPropertiesSet() {
// If configuration-file validation is enabled, check whether the configuration file exists
// It is disabled by default
checkConfigFileExists();
}
}
It implements InitializingBean. After Spring instantiates the MybatisAutoConfiguration bean, it calls its afterPropertiesSet method, which checks whether the mybatis.config configuration file exists.
In addition, there is another @Configuration class at the bottom of this class:
@org.springframework.context.annotation.Configuration
@Import({ AutoConfiguredMapperScannerRegistrar.class })// Imports AutoConfiguredMapperScannerRegistrar
@ConditionalOnMissingBean(MapperFactoryBean.class)
public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {
@Override
public void afterPropertiesSet() {
logger.debug("No {} found.", MapperFactoryBean.class.getName());
}
}
The purpose of this class is to import AutoConfiguredMapperScannerRegistrar. We continue by studying it.
2. How Is the Package to Scan Determined?
AutoConfiguredMapperScannerRegistrar starts scanning from the package of @MybatisAutoConfiguration, and adds all classes annotated with @Mapper to the container.
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (!AutoConfigurationPackages.has(this.beanFactory)) {
logger.debug("Could not determine auto-configuration package, automatic mapper scanning disabled.");
return;
}
logger.debug("Searching for mappers annotated with @Mapper");
// packages is the package where MybatisAutoConfiguration is located: com.zsk.template
List<String> packages = AutoConfigurationPackages.get(this.beanFactory);
if (logger.isDebugEnabled()) {
packages.forEach(pkg -> logger.debug("Using auto-configuration base package '{}'", pkg));
}
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
if (this.resourceLoader != null) {
scanner.setResourceLoader(this.resourceLoader);
}
// Scan all classes annotated with @Mapper
scanner.setAnnotationClass(Mapper.class);
scanner.registerFilters();
scanner.doScan(StringUtils.toStringArray(packages));
}
Discussion
Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub