1. 前言

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

2. Mybatis Mapper注册机制

Mybatis结合SpringMapper注册到Spring IoC的机制是这样的:

其实里面涉及到SpringMybatis的知识点还是比较多的,但是我们只要梳理出来流程就比较容易理解和掌握。所以阅读源码的精髓在于先掌握一片叶子的脉络,然后各个击破去梳理其走向。所以胖哥梳理出左边的就是右边的“脉络”,接下来我们就一步步剖析它们。

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

BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor的子接口,BeanFactoryPostProcessor的作用是在Spring Bean的定义信息已经加载但还没有初始化的时候执行postProcessBeanFactory()来处理一些额外的逻辑,而BeanDefinitionRegistryPostProcessor的作用是在BeanFactoryPostProcessor增加了一个前置处理,当一个Bean实现了该接口后,始化前先执行该接口的postProcessBeanDefinitionRegistry()方法,然后再执行其父类的方法postProcessBeanFactory()。这样就把一个Spring Bean的初始化周期更加细化,让我们在各个阶段有定制它的可能。

但是对于本文来说这个类其实是可以忽略的,该类只是触发了批量扫描注入逻辑,它并没有实际参与扫描注入。

5. ClassPathBeanDefinitionScanner

从名字上来看这个类就是在类路径下扫描Bean定义并将符合条件的批量通过BeanDefinitionRegistry注册到Spring IoC。它提供了一些默认的过滤器来检出需要被注入Spring IoCBean,默认使用JSR 250JSR 330的两个注解。当然你可以通过addIncludeFilter来新增被包含的Bean,或者addExcludeFilter来排除一些Bean。然后只需要调用其scan方法对特定的包进行扫描注入。

6. FactoryBean

就像MybatisMapper一样,它们具有共同的特点的同时也有一些差异。所以使用FactoryBean接口来创建这些Mapper再合适不过了。关于FactoryBean我在 Spring 中的FactoryBean 与BeanFactory 一文中专门来讲解它,有兴趣的可以去了解。

但是FactoryBean 并不是动态扫描注入的必选步骤。

7. 总结

本文通过对**Mybatis **的注入机制进行了分析来研究ImportBeanDefinitionRegistrar的生命周期和使用。如何通过它来编写我们自己的注入逻辑才是最重要的,后续我会讲一些这方面的实际应用,请持续关注: 码农小胖哥

关注公众号:Felordcn 获取更多资讯

个人博客:https://felord.cn

Mybatis是如何将Mapper接口注册到Spring IoC的的更多相关文章

  1. MyBatis-Spring中间件逻辑分析(怎么把Mapper接口注册到Spring中)

    1.      文档介绍 1.1.      为什么要写这个文档 接触Spring和MyBatis也挺久的了,但是一直还停留在使用的层面上,导致很多时候光知道怎么用,而不知道其具体原理,这样就很难做一 ...

  2. Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring

    Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring 非原创[只为记录],原博文地址:https://www.cnblogs.com/ ...

  3. (转)Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring

    Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring Mybatis在与Spring集成的时候可以配置MapperFactoryBea ...

  4. Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring - 大新博客 - 推酷 - 360安全浏览器 7.1

    Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring - 大新博客 时间 2014-02-11 21:08:00  博客园-所有随笔区 ...

  5. spring与mybatis整合(扫描Mapper接口)

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" ...

  6. 【eclipse】mybatis配置文件创建与mapper接口文件创建

    什么是mybatis: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射. mybatis配置文件: <?xml version="1.0" ...

  7. mybatis入门篇:Mapper接口/关联查询/新增数据

    1.数据准备 2.编写实体类 package com.forest.owl.entity; import java.util.Date; public class User { private Lon ...

  8. mybatis笔记之使用Mapper接口注解

    1. mybatis支持的映射方式 mybatis支持的映射方式有基于xml的mapper.xml文件.基于java的使用Mapper接口class,简单学习一下mybatis使用接口来配置映射的方法 ...

  9. MyBatis逆向工程中的Mapper接口以及Example的实例函数及详解

    一.mapper接口中的方法解析 mapper接口中的函数及方法 方法 功能说明 int countByExample(UserExample example) thorws SQLException ...

随机推荐

  1. async + await 异步

    先执行A在执行B再执行.then里面的AAA() { XXXXX一堆代码 this.BBB().then(()=>{ 其他代码 })}, async BBB(){ let res = await ...

  2. getAnnotation的一个坑

    // TableField annotation = f.getAnnotation(TableField.class); // 不建议使用这个,建议使用下面这个方法获取 TableField ann ...

  3. Spring Security认证流程分析--练气后期

    写在前面 在前一篇文章中,我们介绍了如何配置spring security的自定义认证页面,以及前后端分离场景下如何获取spring security的CSRF Token.在这一篇文章中我们将来分析 ...

  4. 关于c++11 memory order的理解

    关于C++memory_order的理解 看了c++并发编程实战的内存模型部分后,一直对memory_order不太懂,今天在知乎发现了百度的brpc,恰好有关于原子操作的文档,感觉解释的很好.为了加 ...

  5. 怎么下载chrome的扩展程序

    很多时候我们是没办法访问谷歌扩展应用程序 chrome应用商店的,这时候我们最好能把对应扩展应用程序下载保存,以便提供给其他人员使用. 搜索得到知乎有很全的方法: 如何导出并打包第三方chrome扩展 ...

  6. .NetCore使用Redis,StackExchange.Redis队列,发布与订阅,分布式锁的简单使用

    环境:之前一直是使用serverStack.Redis的客服端,今天来使用一下StackExchange.Redis(个人感觉更加的人性化一些,也是免费的,性能也不会差太多),版本为StackExch ...

  7. 放眼SEM现状及发展历程

    http://www.wocaoseo.com/thread-187-1-1.html 由于近年来移动应用的基本普及,搜索引擎营销随之进入高速发展时代,应用层次的提升已经成为企业营销策略的一个重要组成 ...

  8. 深入探究.Net Core Configuration读取配置的优先级

    前言     在之前的文章.Net Core Configuration源码探究一文中我们曾解读过Configuration的工作原理,也.Net Core Configuration Etcd数据源 ...

  9. 面经手册 · 第8篇《LinkedList插入速度比ArrayList快?你确定吗?》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 你以为考你个数据结构是要造火箭? 汽车75马力就够奔跑了,那你怎么还想要2.0涡轮+ ...

  10. ShaderLab 枚举常量

        public enum ZTest     {         Always = 0,         Less = 2,         Equal = 3,         LEqual  ...