Spring Boot Starter for MyBatis integration providing auto-configuration and dependency management
—
The MyBatis Spring Boot Starter provides comprehensive auto-configuration that automatically sets up MyBatis components based on classpath detection and configuration properties. This eliminates the need for manual bean definitions while providing extensive customization options.
Main auto-configuration class that creates and configures essential MyBatis beans.
/**
* Auto-configuration for MyBatis that contributes SqlSessionFactory and SqlSessionTemplate.
* Automatically configures mapper scanning when @MapperScan is not used.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
public class MybatisAutoConfiguration implements InitializingBean {
/**
* Constructor accepting all required dependencies and customizers
*/
public MybatisAutoConfiguration(
MybatisProperties properties,
ObjectProvider<Interceptor[]> interceptorsProvider,
ObjectProvider<TypeHandler[]> typeHandlersProvider,
ObjectProvider<LanguageDriver[]> languageDriversProvider,
ResourceLoader resourceLoader,
ObjectProvider<DatabaseIdProvider> databaseIdProvider,
ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider,
ObjectProvider<List<SqlSessionFactoryBeanCustomizer>> sqlSessionFactoryBeanCustomizers
);
/**
* Creates the main SqlSessionFactory bean with auto-configuration
* @param dataSource the DataSource to use
* @return configured SqlSessionFactory
* @throws Exception if configuration fails
*/
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception;
/**
* Creates the SqlSessionTemplate bean for database operations
* @param sqlSessionFactory the SqlSessionFactory to use
* @return configured SqlSessionTemplate
*/
@Bean
@ConditionalOnMissingBean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory);
/** Validates configuration after properties are set */
@Override
public void afterPropertiesSet();
}Key Features:
SqlSessionFactory and SqlSessionTemplate beansConfigurationCustomizer instancesSqlSessionFactoryBeanCustomizer instancesAuto-configuration for additional MyBatis scripting language drivers.
/**
* Auto-configuration for MyBatis scripting language drivers including
* FreeMarker, Velocity, and Thymeleaf support
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(LanguageDriver.class)
public class MybatisLanguageDriverAutoConfiguration {
private static final String CONFIGURATION_PROPERTY_PREFIX = "mybatis.scripting-language-driver";
/**
* Configuration for legacy FreeMarker language driver (version 1.1.x and under)
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(FreeMarkerLanguageDriver.class)
@ConditionalOnMissingClass("org.mybatis.scripting.freemarker.FreeMarkerLanguageDriverConfig")
public static class LegacyFreeMarkerConfiguration {
@Bean
@ConditionalOnMissingBean
FreeMarkerLanguageDriver freeMarkerLanguageDriver();
}
/**
* Configuration for FreeMarker language driver (version 1.2.x+)
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({FreeMarkerLanguageDriver.class, FreeMarkerLanguageDriverConfig.class})
public static class FreeMarkerConfiguration {
@Bean
@ConditionalOnMissingBean
FreeMarkerLanguageDriver freeMarkerLanguageDriver(FreeMarkerLanguageDriverConfig config);
@Bean
@ConditionalOnMissingBean
@ConfigurationProperties(CONFIGURATION_PROPERTY_PREFIX + ".freemarker")
public FreeMarkerLanguageDriverConfig freeMarkerLanguageDriverConfig();
}
/**
* Configuration for legacy Velocity language driver (version 2.0 and under)
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(org.mybatis.scripting.velocity.Driver.class)
@ConditionalOnMissingClass("org.mybatis.scripting.velocity.VelocityLanguageDriverConfig")
@SuppressWarnings("deprecation")
public static class LegacyVelocityConfiguration {
@Bean
@ConditionalOnMissingBean
org.mybatis.scripting.velocity.Driver velocityLanguageDriver();
}
/**
* Configuration for Velocity language driver (version 2.1.x+)
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({VelocityLanguageDriver.class, VelocityLanguageDriverConfig.class})
public static class VelocityConfiguration {
@Bean
@ConditionalOnMissingBean
VelocityLanguageDriver velocityLanguageDriver(VelocityLanguageDriverConfig config);
@Bean
@ConditionalOnMissingBean
@ConfigurationProperties(CONFIGURATION_PROPERTY_PREFIX + ".velocity")
public VelocityLanguageDriverConfig velocityLanguageDriverConfig();
}
/**
* Configuration for Thymeleaf language driver
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ThymeleafLanguageDriver.class)
public static class ThymeleafConfiguration {
@Bean
@ConditionalOnMissingBean
ThymeleafLanguageDriver thymeleafLanguageDriver(ThymeleafLanguageDriverConfig config);
@Bean
@ConditionalOnMissingBean
@ConfigurationProperties(CONFIGURATION_PROPERTY_PREFIX + ".thymeleaf")
public ThymeleafLanguageDriverConfig thymeleafLanguageDriverConfig();
}
}The auto-configuration includes automatic mapper discovery and registration.
/**
* Automatic mapper scanner that registers all @Mapper annotated interfaces
* when no explicit mapper configuration is provided
*/
public static class AutoConfiguredMapperScannerRegistrar
implements BeanFactoryAware, EnvironmentAware, ImportBeanDefinitionRegistrar {
/**
* Registers mapper scanner configuration when auto-configuration packages are available
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry
);
@Override
public void setBeanFactory(BeanFactory beanFactory);
@Override
public void setEnvironment(Environment environment);
}
/**
* Configuration that triggers automatic mapper scanning when no explicit
* mapper configuration is found
*/
@Configuration(proxyBeanMethods = false)
@Import(AutoConfiguredMapperScannerRegistrar.class)
@ConditionalOnMissingBean({MapperFactoryBean.class, MapperScannerConfigurer.class})
public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {
@Override
public void afterPropertiesSet();
}The auto-configuration only activates when specific conditions are met:
// Only when MyBatis classes are on classpath
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
// Only when exactly one DataSource bean exists
@ConditionalOnSingleCandidate(DataSource.class)
// Only creates beans if they don't already exist
@ConditionalOnMissingBean
// Only scans for mappers if no explicit mapper configuration exists
@ConditionalOnMissingBean({MapperFactoryBean.class, MapperScannerConfigurer.class})The auto-configuration processes components in this order:
For SqlSessionFactory creation:
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
// 1. Set DataSource
factory.setDataSource(dataSource);
// 2. Configure VFS (defaults to SpringBootVFS)
if (properties.getConfiguration() == null || properties.getConfiguration().getVfsImpl() == null) {
factory.setVfs(SpringBootVFS.class);
}
// 3. Set configuration location if specified
if (StringUtils.hasText(this.properties.getConfigLocation())) {
factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
}
// 4. Apply core configuration
applyConfiguration(factory);
// 5. Set configuration properties
if (this.properties.getConfigurationProperties() != null) {
factory.setConfigurationProperties(this.properties.getConfigurationProperties());
}
// 6. Add interceptors
if (!ObjectUtils.isEmpty(this.interceptors)) {
factory.setPlugins(this.interceptors);
}
// 7. Set database ID provider
if (this.databaseIdProvider != null) {
factory.setDatabaseIdProvider(this.databaseIdProvider);
}
// 8. Configure type aliases
if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
}
// 9. Set type handlers
if (!ObjectUtils.isEmpty(this.typeHandlers)) {
factory.setTypeHandlers(this.typeHandlers);
}
// 10. Configure mapper locations
Resource[] mapperLocations = this.properties.resolveMapperLocations();
if (!ObjectUtils.isEmpty(mapperLocations)) {
factory.setMapperLocations(mapperLocations);
}
// 11. Configure scripting language drivers
if (!ObjectUtils.isEmpty(this.languageDrivers)) {
factory.setScriptingLanguageDrivers(this.languageDrivers);
}
// 12. Apply SqlSessionFactoryBean customizers
applySqlSessionFactoryBeanCustomizers(factory);
// 13. Build and return SqlSessionFactory
return factory.getObject();
}@SpringBootApplication(exclude = {MybatisAutoConfiguration.class})
public class Application {
// Auto-configuration disabled - manual configuration required
}@Configuration
@AutoConfigureBefore(MybatisAutoConfiguration.class)
public class CustomMybatisAutoConfiguration {
@Bean
@Primary
public DataSource customDataSource() {
// Custom DataSource that will be used by MyBatis auto-configuration
return new HikariDataSource();
}
@Bean
public Interceptor customInterceptor() {
// Custom interceptor that will be automatically registered
return new AuditInterceptor();
}
}@Configuration
public class MyBatisOverrides {
// This will prevent auto-configuration from creating SqlSessionTemplate
@Bean
@Primary
public SqlSessionTemplate customSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new CustomSqlSessionTemplate(sqlSessionFactory);
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-mybatis-spring-boot--mybatis-spring-boot-starter