MyBaits自动配置原理 (2)

MybatisAutoConfiguration#sqlSessionTemplate

@Bean @ConditionalOnMissingBean public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { ExecutorType executorType = this.properties.getExecutorType(); return executorType != null ? new SqlSessionTemplate(sqlSessionFactory, executorType) : new SqlSessionTemplate(sqlSessionFactory); }

到这里也就知道了MyBatis自动配置其实就是替我们完成了SqlSessionFactory和SqlSessionTempate的创建, 省去了自己导入相关依赖和配置相关Bean的麻烦.

MybatisLanguageDriverAutoConfiguration

这个类的配置是对各个语言的支持,比如Thymeleaf, Velocity,LegacyVelociy, FreeMarker等视图组件的支持。

@Configuration @ConditionalOnClass({LanguageDriver.class}) public class MybatisLanguageDriverAutoConfiguration { private static final String CONFIGURATION_PROPERTY_PREFIX = "mybatis.scripting-language-driver"; public MybatisLanguageDriverAutoConfiguration() { } @Configuration @ConditionalOnClass({ThymeleafLanguageDriver.class}) public static class ThymeleafConfiguration { public ThymeleafConfiguration() { } } @Configuration @ConditionalOnClass({VelocityLanguageDriver.class, VelocityLanguageDriverConfig.class}) public static class VelocityConfiguration { public VelocityConfiguration() { } } @Configuration @ConditionalOnClass({Driver.class}) @ConditionalOnMissingClass({"org.mybatis.scripting.velocity.VelocityLanguageDriverConfig"}) public static class LegacyVelocityConfiguration { public LegacyVelocityConfiguration() { } } @Configuration @ConditionalOnClass({FreeMarkerLanguageDriver.class, FreeMarkerLanguageDriverConfig.class}) public static class FreeMarkerConfiguration { public FreeMarkerConfiguration() { } } @Configuration @ConditionalOnClass({FreeMarkerLanguageDriver.class}) @ConditionalOnMissingClass({"org.mybatis.scripting.freemarker.FreeMarkerLanguageDriverConfig"}) public static class LegacyFreeMarkerConfiguration { public LegacyFreeMarkerConfiguration() { } } }

MybatisLanguageDriverAutoConfiguration类在org.mybatis.spring.boot.autoconfigure包下,我删掉了内部静态类下的代码,为了保持这个类看起来更直观

自定义Mapper是如何被扫描的

业务开发中,我们是声明接口(Mapper),那么我们自定义的Mapper是如何被扫描的呢, 我们继续顺着MybatisAutoConfiguration代码分析,其内部包含了一个AutoConfiguredMapperScannerRegistrar的内部静态类.

AutoConfiguredMapperScannerRegistrar

registerBeanDefinitions

public static class AutoConfiguredMapperScannerRegistrar implements BeanFactoryAware, ImportBeanDefinitionRegistrar { private BeanFactory beanFactory; public AutoConfiguredMapperScannerRegistrar() { } public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { if (!AutoConfigurationPackages.has(this.beanFactory)) { } else { //1.获取到SpringBoot的基础包路径 List<String> packages = AutoConfigurationPackages.get(this.beanFactory); //2.生成一个BeanDefinition的构造器,用于构建MapperScannerConfigurer的 //BeanDefinition BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class); builder.addPropertyValue("processPropertyPlaceHolders", true); //3.设置@Mapper注解的接口才会被当成Mapper接口 builder.addPropertyValue("annotationClass", Mapper.class); builder.addPropertyValue("basePackage", StringUtils.collectionToCommaDelimitedString(packages)); BeanWrapper beanWrapper = new BeanWrapperImpl(MapperScannerConfigurer.class); //4.获取MapperScannerConfigurer的属性名称 Set<String> propertyNames = (Set)Stream.of(beanWrapper.getPropertyDescriptors()).map(FeatureDescriptor::getName).collect(Collectors.toSet()); if (propertyNames.contains("lazyInitialization")) { builder.addPropertyValue("lazyInitialization", "${mybatis.lazy-initialization:false}"); } if (propertyNames.contains("defaultScope")) { builder.addPropertyValue("defaultScope", "${mybatis.mapper-default-scope:}"); } //5.这里添加一个MapperScannerConfigurer的BeanDefinition对象,也就是注入一个 //MapperScannerConfigurer对象 registry.registerBeanDefinition(MapperScannerConfigurer.class.getName(), builder.getBeanDefinition()); } } public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } }

AutoConfiguredMapperScannerRegistrar类是MybatisAutoConfiguration的内部静态类,位于包org.mybatis.spring.boot.autoconfigure下。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjjxx.html