Mybatis是如何将Mapper接口注册到Spring IoC的

1. 前言
有时候我们需要自行定义一些注解来标记某些特定功能的类并将它们注入Spring IoC容器。比较有代表性的就是Mybatis的Mapper接口。假如有一个新的需求让你也实现类似的功能你该如何下手呢?今天我们就从Mybatis的相关功能入手来学习其思路并为我所用。
2. Mybatis Mapper注册机制
Mybatis结合Spring将Mapper注册到Spring IoC的机制是这样的:

其实里面涉及到Spring和Mybatis的知识点还是比较多的,但是我们只要梳理出来流程就比较容易理解和掌握。所以阅读源码的精髓在于先掌握一片叶子的脉络,然后各个击破去梳理其走向。所以胖哥梳理出左边的就是右边的“脉络”,接下来我们就一步步剖析它们。
3. ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar是一个非常重要的接口,凡是要把第三方整合到Spring的开发者都应该掌握这个接口。这接口用来动态的注册某一些具有相同特征的一批类到Spring IoC,用法有点类似 ImportSelector接口,借助于@Import注解“附着在”自定义的注解上,就像Mybatis-Spring的用法一样。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperScannerRegistrar.class)
@Repeatable(MapperScans.class)
public @interface MapperScan {
// 省略
}
也可以直接附着到标记有@Configuration或者具有相同功能的配置类上。
@Import(MapperScannerRegistrar.class)
@Configuration
public class MyConfig {
}
它只有一个方法:
void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
其中参数importingClassMetadata包含了@Import所依附的配置类上的所有注解。这意味着我们可以拿到对应注解的元信息并作为我们动态导入的判断依据,上面就是从@MapperScan获取了Mapper所在的包以及其它信息。而BeanDefinitionRegistry就是用来注册Spring Bean的。那么到底是如何注册的呢?我们接着往下看。
4. BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,BeanFactoryPostProcessor的作用是在Spring Bean的定义信息已经加载但还没有初始化的时候执行postProcessBeanFactory()来处理一些额外的逻辑,而BeanDefinitionRegistryPostProcessor的作用是在BeanFactoryPostProcessor增加了一个前置处理,当一个Bean实现了该接口后,始化前先执行该接口的postProcessBeanDefinitionRegistry()方法,然后再执行其父类的方法postProcessBeanFactory()。这样就把一个Spring Bean的初始化周期更加细化,让我们在各个阶段有定制它的可能。
但是对于本文来说这个类其实是可以忽略的,该类只是触发了批量扫描注入逻辑,它并没有实际参与扫描注入。
5. ClassPathBeanDefinitionScanner
从名字上来看这个类就是在类路径下扫描Bean定义并将符合条件的批量通过BeanDefinitionRegistry注册到Spring IoC。它提供了一些默认的过滤器来检出需要被注入Spring IoC的Bean,默认使用JSR 250和JSR 330的两个注解。当然你可以通过addIncludeFilter来新增被包含的Bean,或者addExcludeFilter来排除一些Bean。然后只需要调用其scan方法对特定的包进行扫描注入。
6. FactoryBean
就像Mybatis的Mapper一样,它们具有共同的特点的同时也有一些差异。所以使用FactoryBean接口来创建这些Mapper再合适不过了。关于FactoryBean我在 Spring 中的FactoryBean 与BeanFactory 一文中专门来讲解它,有兴趣的可以去了解。
但是
FactoryBean并不是动态扫描注入的必选步骤。
7. 总结
本文通过对**Mybatis **的注入机制进行了分析来研究ImportBeanDefinitionRegistrar的生命周期和使用。如何通过它来编写我们自己的注入逻辑才是最重要的,后续我会讲一些这方面的实际应用,请持续关注: 码农小胖哥。
关注公众号:Felordcn 获取更多资讯
Mybatis是如何将Mapper接口注册到Spring IoC的的更多相关文章
- MyBatis-Spring中间件逻辑分析(怎么把Mapper接口注册到Spring中)
1. 文档介绍 1.1. 为什么要写这个文档 接触Spring和MyBatis也挺久的了,但是一直还停留在使用的层面上,导致很多时候光知道怎么用,而不知道其具体原理,这样就很难做一 ...
- Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring
Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring 非原创[只为记录],原博文地址:https://www.cnblogs.com/ ...
- (转)Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring
Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring Mybatis在与Spring集成的时候可以配置MapperFactoryBea ...
- Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring - 大新博客 - 推酷 - 360安全浏览器 7.1
Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring - 大新博客 时间 2014-02-11 21:08:00 博客园-所有随笔区 ...
- spring与mybatis整合(扫描Mapper接口)
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" ...
- 【eclipse】mybatis配置文件创建与mapper接口文件创建
什么是mybatis: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射. mybatis配置文件: <?xml version="1.0" ...
- mybatis入门篇:Mapper接口/关联查询/新增数据
1.数据准备 2.编写实体类 package com.forest.owl.entity; import java.util.Date; public class User { private Lon ...
- mybatis笔记之使用Mapper接口注解
1. mybatis支持的映射方式 mybatis支持的映射方式有基于xml的mapper.xml文件.基于java的使用Mapper接口class,简单学习一下mybatis使用接口来配置映射的方法 ...
- MyBatis逆向工程中的Mapper接口以及Example的实例函数及详解
一.mapper接口中的方法解析 mapper接口中的函数及方法 方法 功能说明 int countByExample(UserExample example) thorws SQLException ...
随机推荐
- 地图绘制之basemap第一弹 basemap选择与安装
作为一个测绘GIS专业的学生,会有很多绘制地图的需求,一般情况使用ArcGIS.QGIS就可以解决,但是在绘制如论文插图时需要使用更加专业可定制化程度更高的工具,专业传统一般使用GMT,几经比较,最终 ...
- linux命令--大小写转换命令
1.tr命令 tr命令转换小写为大写 cat aa.txt | tr a-z A-Z 或者 cat aa.txt | tr [:lower:] [:upper:] tr命令大写转换小写 ...
- 初识ABP vNext(5):ABP扩展实体
Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 目录 前言 开始 扩展实体 路由整理 最后 前言 上一篇实现了前端vue部分的用户登录和菜单权限控制,但是有一些问题需要解决,比如用户头 ...
- SpringBoot项目 使用Jenkins进行自动化部署 (gitLab管理项目)_
1.部署服务器创建好对应文件夹和启动脚本 创建文件夹 mkdir /wdcloud/app/rps/rps-module-category 创建启动脚本 cd /wdcloud/app/rps/rps ...
- c++线性表和数组的区别
在传统C语言程序中,描述顺序表的存储表示有两种方式:静态方式.动态方式 顺序表的静态存储表示: #define maxSize 100 typedefintT; typedefstruct{ T da ...
- 7. Jackson用树模型处理JSON是必备技能,不信你看
每棵大树,都曾只是一粒种子.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众号[BA ...
- idea,git操作
原文地址:https://blog.csdn.net/lzx2018/article/details/91414591 1新建分支 点击New Branch 2切换分支
- IDEA创建MAVEN项目并使用tomcat启动
一.开发环境准备 1.JDK1.8,已经配置好环境变量 2.IDEA2019.2,目前稳定版里面个人认为还不错的 3.tomcat服务器,笔者使用的是apache-tomcat-8.5.57 4.使用 ...
- Laravel Pipeline原理及使用
Laravel Pipeline原理及使用 开发中可能遇到非常冗长的逻辑,以至于我们想将针对性逻辑拆分出来,但是又拿不准该如何拆分才能实现较高的扩展性并保证较高的维护性,或者说不知道如何优雅的将待处理 ...
- Mac 安装多个版本jdk
JDK默认安装路径为/Library/Java/JavaVirtualMachines 多版本安装后效果为: 设置 1.执行以下命令 cd ~ open -e .bash_profile #打开.ba ...