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的生命周期和使用。如何通过它来编写我们自己的注入逻辑才是最重要的,后续我会讲一些这方面的实际应用,
相关文章
- Spring学习笔记(五)——JdbcTemplate和spring中声明式事务
- spring boot自动配置原理面试题_Spring boot面试
- Spring学习笔记(十八)——spring日志框架的配置和使用
- Spring MVC框架学习(二)---- 使用原生的配置 熟悉 SpringMVC 的执行流程
- 吃透Spring框架(一)
- Spring同一接口有多个实现类,如何注入
- spring注解@Conditional 按照一定的条件进行判断,满足条件给容器中注册bean
- mybatis3源码解析--spring下mapper注册详解
- Spring监听器-spring源码详解(五)
- Spring Redis中使用Lua脚本实现高并发原子操作
- Spring Boot的性能优化(三)
- 小宇宙爆发!Spring Boot 新特性:节省95%内存占用
- spring的AOP(五)—-Spring AOP 编程(AspectJ )详解编程语言
- Spring Cloud(二):Spring Cloud Eureka Server高可用注册服务中心的配置详解编程语言
- Spring自动装配Bean
- spring架构利器:JFinal MySQL Spring(jfinalmysql)
- spring动态bean注册示例分享