Mybatis是如何向Spring注册Mapper的
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
的生命周期和使用。如何通过它来编写我们自己的注入逻辑才是最重要的,后续我会讲一些ImportBeanDefinitionRegistrar的实际应用。
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 代码防御性编程的十条技巧
- Ubuntu终端多窗口分屏Terminator
- linux 编译安装python3.6的教程详解
- Unix/Linux系统下的nobody用户与nologin详细介绍
- 详解flutter engine 那些没被释放的东西
- Centos7安装PHP及Nginx的教程详解
- Flutter Image实现图片加载
- Centos7系统下搭建.NET Core2.0+Nginx+Supervisor环境
- CentOS7 LNMP+phpmyadmin环境搭建 第二篇LNMP环境搭建教程
- 详解Linux 下开发微信小程序安装开发工具
- Linux一个增强的截图及分享工具:ScreenCloud
- linux 命名管道实例详解
- 11个JavaScript代码重构最佳实践
- Linux中在不破坏磁盘的情况下使用dd命令
- Jexus开机自动启动配置方法