当前位置: 首页 > news >正文

Mybatis源码解析

MybatisAutoConfiguration或者MybatisPlusAutoConfiguration核心作用是初始化工厂类SqlSessionFactory,其中包含属性interceptors、MapperLocations、TypeAliasesPackage、TypeEnumsPackage、TypeHandlers等。

MybatisAutoConfiguration自动装配类是由依赖:mybatis-spring-boot-starter【mybatis-spring-boot-autoconfigure】提供的,如果使用Mp版本则直接由MybatisPlusAutoConfiguration替代MybatisAutoConfiguration。


@Mapper通过@Import注解导入ImportBeanDefinitionRegistrar类型的实现类MapperScannerRegistrar,类ImportBeanDefinitionRegistrar的作用:

  1. 核心是引入类MapperScannerConfigurer,初始化其对应的BeanDefinition,并注册至IOC中BeanDefinition类型的注册表中。
  2. MapperScannerConfigurer实为BeanDefinitionRegistryPostProcessor类型的后置处理器。
  3. 注解@MapperScan相关属性value重置到MapperScannerConfigurer对应的BeanDefinition内部。
  4. 将MapperScannerConfigurer对应的BeanDefinition注册至Spring IOC容器内部。

BeanDefinitionRegistryPostProcessor类型的后置处理器MapperScannerConfigurer:此时@Mapper注解相关属性重置于MapperScannerConfigurer

  1. 扫描basePackages路径下全部的Mapper接口。
  2. 遍历每一个接口为其生成BeanDefinition,其内部beanClass属性value为MapperFactoryBean
  3. 将@Mapper组合注解相关属性转化为MapperFactoryBean相关字段或者方法属性。

@Mapper -> MapperScannerRegistrar -> MapperScannerConfigurer-> MapperFactoryBean转化流程:

public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar{public void registerBeanDefinitions(AnnotationAttributes annoAttrs,BeanDefinitionRegistry registry, String beanName) {BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);...// 将 @MapperScan 属性sqlSessionTemplateRef 作为 MapperScannerConfigurer的属性sqlSessionTemplateRefString sqlSessionTemplateRef = annoAttrs.getString("sqlSessionTemplateRef");if (StringUtils.hasText(sqlSessionTemplateRef)) {builder.addPropertyValue("sqlSessionTemplateBeanName",annoAttrs.getString("sqlSessionTemplateRef"));}// 将 @MapperScan 属性sqlSessionFactoryRef 作为 MapperScannerConfigurer的属性sqlSessionFactoryBeanNameString sqlSessionFactoryRef = annoAttrs.getString("sqlSessionFactoryRef");if (StringUtils.hasText(sqlSessionFactoryRef)) {builder.addPropertyValue("sqlSessionFactoryBeanName",annoAttrs.getString("sqlSessionFactoryRef"));}...registry.registerBeanDefinition(beanName, builder.getBeanDefinition());}
}

以上将注解@MapperScan 属性转移到MapperScannerConfigurer。

public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean{private boolean addToConfig = true;private SqlSessionFactory sqlSessionFactory;private SqlSessionTemplate sqlSessionTemplate;private String sqlSessionFactoryBeanName;private String sqlSessionTemplateBeanName;public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);//以下将 @MapperScan 相关属性转移到 ClassPathMapperScannerscanner.setAddToConfig(this.addToConfig);scanner.setAnnotationClass(this.annotationClass);scanner.setMarkerInterface(this.markerInterface);scanner.setSqlSessionFactory(this.sqlSessionFactory);scanner.setSqlSessionTemplate(this.sqlSessionTemplate);scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);scanner.setResourceLoader(this.applicationContext);scanner.setBeanNameGenerator(this.nameGenerator);scanner.setMapperFactoryBeanClass(this.mapperFactoryBeanClass);scanner.registerFilters();scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage,",; \t\n"));}
}

 将 MapperScannerConfigurer 相关属性转移到类ClassPathMapperScanner。

public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {private Class<? extends MapperFactoryBean> mapperFactoryBeanClass = MapperFactoryBean.class;private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {GenericBeanDefinition definition;for (BeanDefinitionHolder holder : beanDefinitions) {//basePackages路径下扫描得到全部Mapper接口...// 将 Mapper接口之 GenericBeanDefinition 的BeanClass属性为 MapperFactoryBeandefinition.setBeanClass(this.mapperFactoryBeanClass);// 给 MapperFactoryBean 添加属性字段 addToConfigdefinition.getPropertyValues().add("addToConfig", this.addToConfig);boolean explicitFactoryUsed = false;// 给 MapperFactoryBean 添加属性字段 sqlSessionFactoryif (StringUtils.hasText(this.sqlSessionFactoryBeanName)) {definition.getPropertyValues().add("sqlSessionFactory",new RuntimeBeanReference(this.sqlSessionFactoryBeanName));explicitFactoryUsed = true;} else if (this.sqlSessionFactory != null) {definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory);explicitFactoryUsed = true;}// 给 MapperFactoryBean 添加属性字段 sqlSessionTemplateif (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {definition.getPropertyValues().add("sqlSessionTemplate",new RuntimeBeanReference(this.sqlSessionTemplateBeanName));explicitFactoryUsed = true;} else if (this.sqlSessionTemplate != null) {definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate);explicitFactoryUsed = true;}definition.setLazyInit(lazyInitialization);}}
}

http://www.lryc.cn/news/373588.html

相关文章:

  • 前端学习CSS之神奇的块浮动
  • 【Java】内部类、枚举、泛型
  • LabVIEW电子类实验虚拟仿真系统
  • SVM支持向量机
  • 【Unity】RPG2D龙城纷争(二)关卡、地块
  • mediamtx流媒体服务器测试
  • C# 循环
  • PHP杂货铺家庭在线记账理财管理系统源码
  • 机器学习中的神经网络重难点!纯干货(上篇)
  • [DDR4] DDR1 ~ DDR4 发展史导论
  • 享元和代理模式
  • [英语单词] ellipsize,动词化后缀 -ize
  • 自然资源-测绘地信专业术语,值得收藏!
  • 如何在小程序中实现页面之间的返回
  • 深入解析数据结构之B树:平衡树中的王者
  • 18. 第十八章 继承
  • OperationalError: (_mysql_exceptions.OperationalError)
  • DocGraph相关概念
  • MySQL限制登陆失败次数配置
  • 洛谷题解 - P1192 台阶问题
  • Unity贪吃蛇改编【详细版】
  • React中数据响应式原理
  • 【FreeRTOS】ARM架构汇编实例
  • 【Linux】常见指令的使用
  • C#面:详细阐述什么是 DTO
  • 「TCP 重要机制」三次握手四次挥手
  • Java数据库编程
  • 决策树算法介绍:原理与案例实现
  • 业务代表模式
  • LeetCode 算法:反转链表 c++