Mybatis底层源码以及与spring整合的源码
可先去看一下spring底层,资料:点击跳转
mybtis与spring整合视频资料:点击跳转
mybatis底层的实现视频资料:点击跳转
一. 简单模拟Mybatis底层源码(具体是如何解析注解sql或者如何调用的jdbc,可以去看一下上面的视频链接)
mybatis单独使用的时候,具体使用步骤是,先创建一个SqlSessionFactory(我这里是模拟,所以赋值为null),然后由SqlSessionFactory创建出一个SqlSession,再由SqlSession.getMapper(CityMapper.class)产生一个CityMapper.class的动态代理的对象
下面为了更好的了解mybtis的底层实现,我们先手动的模拟的写一个mybatis(SqlSessionFactory的作用就是为了产生sqlSession,所以我们就不模拟SqlSessionFactory了,而是直接从sqlSession开始模拟)
以上就是模拟的mybtis的实现原理,那么现在的项目中越来越多的使用Spring,所以我们就需要想办法,如何将mybtis与spring进行融合呢?下面的图中提出了我们的问题,就是如何把mybtis创建好了的mapper对象交给spring管理呢??(spring之前管理的对象都是由spring自己创建,然后自己管理,程序员只需要告诉spring哪些类需要创建对象)
**方案一:**在每个services里用mybatis手动的创建一个mapper(这种方案肯定是不行的,并没有实现mybtis与spring的融合)
**方案二:**用Spring中的@Bean指令(这种方案有个很严重的问题就是,有多少的mapper,就需要写多少个@Bean)
**方案三:**使用FactoryBean(当某个类实现了FactoryBean,且加入到Spring容器中,即类上面加了@Component,那么这个类的实例化过程就和普通类会有些差别,这个差别就是spring不仅会将这个类本身进行实例化,还会将getObject()中创建的对象直接加到spring容器中进行管理)
但是方案三和方案二一样得鸡肋,如果有多个mapper就得写多个类来实现FactoryBean,如下图中我想将CityService交给spring管理得话,还需要再写一个类似得实现类,这样得话,mybtis和Spring得整合并没有很优雅
方案四: 对方案三进行改进,不将getObject()方法中得对象写死,而是通过传参得形式,一旦使用传参的形式,那么就不能直接的加@Component了,因为这个注解没有办法进行传参,那么就需要我们用到Spring的xml配置文件了,有多个mapper的话只需要在xml中加bean就行
方案五:对方案四进行改进,我们的目的是不需要对xml中的bean进行配置,那么不需要bean的话,问题就在于ZiluMapperFactoryBean就没有办法进行实例化,那么getObject()方法中的对象就更不用说了,那么我们怎么解决在不借助xml bean的情况下还可以实现呢??这里就需要用到spring的后置处理器ImportBeanDefinitionRegistrar
- ImportBeanDefinitionRegistrar类只能通过其他类@Import的方式来加载,通常是启动类或配置类。
- 使用@Import,如果括号中的类是ImportBeanDefinitionRegistrar的实现类,则会调用接口方法
- 将其中要注册的类注册成bean。
实现该接口的类拥有注册bean的能力。(这一注册过程和注册加了@Component注解的类同期进行)
方案五就是mybatis结合spring的底层实现