Mybatis 如何与Spring 容器整合在一起的

1 篇文章 0 订阅
1 篇文章 0 订阅

要想知道Mybatis 如何与Spring 框架整合在一起,首先得思考以下几个问题:

1、定义的Mapper接口是怎样被“实现”的?

2、Mapper接口是怎么被Spring发现的,又是怎样被注入到Spring Context 里的?

3、Spring 是怎样通过接口名称找到实现具体Mapper 接口的代理的?

4、这个代理有是怎样找到Mapper的配置文件的?

5、找到了配置文件,又是怎样将接口定义的方法与配置文件一一对应的?

6、配置文件又是如何被解析出来,变成具体的Sql实现的?

7、数据源又是如何被Spring注入的?

开始阅读源代码,思考怎样实现?

1、定义的Mapper接口,使用Spring的主键例如@Autowired 或者@mapper 都能自动被代理,通过接口名,既Spring Context里标识的Bean ID ,注入了代理的对象,框架自己实现InvocationHandler 。 

  •  Spring怎样找到你的Mapper接口类?指定包路径,通过继承ClassPathBeanDefinitionScanner实现自己的Bean定义扫描,加载自己的类,然后就能知道 Mapper 的接口和定义的 方法
  • 那mapper的SQL配置文件是如何与Mapper 类关联的?要保证配置文件的映射空间是mapper的全路径,方法名称既是配置文件的ID,这样就能 将 mapper的sql定义与 接口一一映射了,配置文件的每个id 对应每一个方法。

       图中有【MapperScan】自定义的注解,就是要加载自定义的mapper bean definition 到spring 容器的,

  (1)但是Spring 怎样会加载我们自己定义的注解呢?

 通过@Configuration注解,这个会被Spring 扫描到,然后发现了我们的注解@MapperScan

 (2)加载了这个注解之后,Spring又是怎么来知道@mapperScan是来干什么的?

得模仿@Autowired注解的实现,Autowired会将扫描类下面的每个非静态字段或者setter方法,看看有没有这个注解,若有,将会通过字段的类型去spring容器里找到实现(本质也是代理)并注入,这样就能引入了,

(3)怎样让Spring 加载自己自定义的注解?

这就是在@MapperScan中加入Spring的注解@Import ,既是导入一个配置类MapperScannerRegister

这个类会被Spring加载,Spring发现他实现了ImpoerBeanDefinitionRegistar这个接口,就会调用这个registerBeanDefinition的方法,顾名思义就是按照Spring的规则,注册自己的bean definition到Spring 的注册机中【BeanDefinitionRegister】

(4)怎样找到了mapper? 

在注册Bean 定义的方法里,他能找到已经注册的@mapperSacan这个注解,从而找到这个注解里面的数据是指定了Mapper的路径,找到了 mapper ,使用自己实现的类扫描去扫描这个路径,加载mapper,在这里来一个一个的去注册mapper代理


(5)又是怎样将mapper 注册到 spring 容器中?

下面就是自己实现的类扫描ClassPathMapperScanner,继承自Spring原生的ClassPathBeanDefinition,这就是开始注册自己的bean ,在这里发现获取到spring 给的【mapper的原生的类定义】后,类名没有修改【ID没有修改】但是将类修改成了MapperFactoryBean, 【修改了具体的实现】

过构造器注入了原来的mapper的类名,下面开始往MapperFactoryBean里注入数据源等属性,

这就是Spring bean 定义的修改器。


(6)既然通过mapper类名这个ID, 找到的是MapperFacttoryBean ,那这个类有什么用呢?

    其实这个bean只是一个工厂方法,实现了Spring 定义的FactoryBean,所有得调用他的getObject()方法,才是真正注入的对象。

    截图中,Spring发现这个bean是一个 工厂bean,会直接获取它真实的 bean.



 小段总结:

通过@Configuration @Import【spring 原生的注解】往spring容器里加载了自己自定义的注解 

@mapperScan【告诉mapper在哪里】和【MapperScanRegistar】导入bean定义的类【将mapper的bean definition 注入到Spring容器中,ID 是接口名,类是mapperFactoryBean,工厂方法,真实的对象是sqlSession.getMapper(mapper接口类) 】

(7)sqlSession是哪里来的?他主要干了什么?

   首先这个sqlSession是SqlSessionFactory或者是SqlSessionTemplate,在第一张图中就已经通过@bean 加入了Spring 容器。

  主要工作是解析mapper配置的xml文件,并保存。key 就是 接口类。

    

  (8)那这个sqlSession.getMapper(mapper接口类) 返回的对象是什么呢?

      发现每个Mapper 都映射成MapperProxyFactory,  顾名思义就是mapper的代理工厂,具体的对象就是返回一个代理对象。

     所以,最后具体实现方法的是handder =>【MapperProxy】通过Method 找到=>MapperMethod

   每个mapper 的方法都映射成一个MapperMethod.  MapperMethod 有sqlCommand ,有他来执行方法。

         



最后总结

 1、定义的Mapper接口是怎样被“实现”的?

2、Mapper接口是怎么被Spring发现的,又是怎样被注入到Spring Context 里的?

自定义的注解加载了mapper到Spring 容器,ID 是接口名,注入的具体类是一个动态的代理对象.

被调用时,真正处理任务的是 hander 【MapperProxy】

3、Spring 是怎样通过接口名称找到实现具体Mapper 接口的代理的?

添加了Spring的注解@Autowired 通过类名【ID】在Spring容器里找到的bean definition.

6、配置文件又是如何被解析出来,变成具体的Sql实现的?

7、数据源又是如何被Spring注入的?

4、这个代理又是怎样找到Mapper的配置文件的?

 Spring加载了SqlSessionFactory ,注入了数据源,此时mybatis的数据源就交给了Spring注入,在这里定义了配置文件。

       最后也是通过这个方法注入的:sqlSession.getMapper(mapper接口类) 

5、找到了配置文件,又是怎样将接口定义的方法与配置文件一一对应的?

 配置文件映射的空间 应该是 mapper 类路径。


写在最后,想怎样实现自己的注解,可以参考Spring 自定义的注解实现。
思绪和排版一样有点混乱。
 


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值