Mybatis是如何向Spring注册Mapper的

提兵百万西湖上,立马吴山第一峰!这篇文章主要讲述Mybatis是如何向Spring注册Mapper的相关的知识,希望能为你提供帮助。


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





【Mybatis是如何向Spring注册Mapper的】

其实里面涉及到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?? 并不是动态扫描注入的必选步骤。
7. 总结本文通过对Mybatis的注入机制进行了分析,目的是研究??ImportBeanDefinitionRegistrar??的生命周期和使用。
原作者: 码农小胖哥








    推荐阅读