Fork me on GitHub

MyBatis源码解析【5】工厂的构建

前言

这个分类比较连续,如果这里看不懂,或者第一次看,请回顾之前的博客

http://www.cnblogs.com/linkstar/category/1027239.html

终于算是把装备弄齐全了。接下来就一步步看看MyBatis是如何工作的。

那么我们学习组件的时候就知道了,首先需要构建一个工厂。

那么我们今天就来看看这个工厂是如何建造出来的。

 

建造工厂大致步骤

我们先从外部的我们第一次使用MyBatis的代码开始看看工厂是如何建造的。

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

1、我们需要一个配置文件 mybatis-config.xml

2、利用一个叫Resources的类的getResourceAsStream方法从xml文件中获取里面的内容

3、然后用SqlSessionFactoryBuilder也就是之前说的工厂构建者把获取的资源传进去就构建出了我们需要使用的工厂

 

建造工厂的内部过程

从大致步骤我们看起来好像很容易的样子。但是实际其实复杂的很呢。

我们慢慢来分析。

1、首先我们可以确定的是,MyBatis建造工厂的时候肯定从我们配置的xml中获取了相应的配置信息,然后就能构建出我们想要的工厂了。(只有我们想要的工厂才能生产出我们想要的产品嘛)

2、前面两个步骤就我们知道就是把我们的资源给转换成一个InputStream(可能建造者就认识这样的配置信息吧)

3、那么我们的重点目标就应该放在SqlSessionFactoryBuilder的build方法上面咯,那么走,我们进源码。(如果你是一步步跟前面的博客来的话,那么源码应该点一下就进去了。。。)

image

其中我们看到了,建造之前需要对xml的资源进行读取。将我们的配置资源转换成了一个XMLConfigBuilder类。

这个类可想而知就是为了解析XML而生的一个类。

具体XML的解析我肯定就不仔仔细细讲了,因为解析XML的方式很多。我们就看看MyBatis解析XML需要那些XML里面的东西咯。

我们进入parser.parse()的parse方法。

image

然后我们注意一下,这个parse方法的返回值,Configuration

也就是说MyBatis把读取到的数据保存到了一个Configuration类中。

跟上节奏哦!!!

然后我们回到上一张图中的最下方的build方法

也就是

public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
可以看见入参就是Configuration如果你有兴趣那么可以直接进入Configuration类里面去看看。里面就是各种各样的配置信息了。当然我们关注的点不在这里,所以就不仔细看那些配置了。

 

我们的重点在这里的返回值是一个SqlSessionFactory工厂。但是看最后new的对象是DefaultSqlSessionFactory看名字我们知道是一个叫做默认的工厂。那么我们重点就是在这里,这个默认工厂怎么就造起来了呢?

 

默认工厂、DefaultSqlSessionFactory的构建

首先我们进入DefaultSqlSessionFactory这个类里面去看看。

image

一进去我就看到了这个这里我们可以看出两个点:SqlSessionFactory在MyBatis中是一个接口而不是一个类,DefaultSqlSessionFactory实现了这个接口。DefaultSqlSessionFactory这个类不是很长,我们来看看里面的方法,最后再来看看构造方法。

image

如果你仔细看看,就会发现上面生产产品的方法都是调用的最后的openSessionFromDataSource

 

 

openSessionFromConnection这两个方法。里面到底干啥了呢?其实从入参和出参我们可以看出。(两个方法类似,我就挑一个来讲)根据执行类型,事务隔离性,是否自动提交来创建DefaultSqlSession因为我们最后的产品是要执行sql语句的,所以我们的产品也就是会话里面会带有很多的执行参数,到底这个产品要做成什么样。

image

这里我们需要有一些觉悟,源码里代码规范还是不错的,你看,一个在之后的不会被改变的变量就用了final进行了修饰,如果你来写会这样写吗?这里只是生产产品而已,对于产品的执行我们会在之后细讲。之后我们就来看看这个构造方法;其实构造方法贼简单,就是单纯的赋值了一下,你以为有多难??public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}

 

产品的生产

最后我们来看看产品的生产,为之后的产品的执行做个准备。

首先进入return new DefaultSqlSession(configuration, executor, autoCommit);

image

我们可以看到,也是很简单的一个构造方法,也是设置了必要的参数主要我们先来大致浏览一下这个类

image

可以看见,SqlSession也是一个接口,而我们的默认产品是实现了这个接口。我们看看这个接口有哪些方法其实就很明了了由于方法很多,我就不展示全部了。

image

从方法名字是不是就很熟悉了,就是执行sql语句的方法嘛。所以我们的产品原来就是这样的。

 

总结

最后总结一下:其实工厂的构建其实还算是简单的,我们需要注意的点是,构建过程中,读取了xml配置,把配置加载加载进了类里面,而且配置的读取是有一个顺序的。

配置的不同导致了最后工厂建立的不同,导致了最后生产的产品不同。

所有真正的工厂和产品都是接口,而使用的都是默认工厂和默认产品,去实现了这些接口,一般情况下我们不可能自己去实现这些接口然后去开发的。

最后依然留下几个问题:

1、为什么MyBatis要这样设计?为什么要设计成工厂这样的模式呢?有什么样的好处?

2、接口在这里的好处是什么?

3、Configuration这个类的作用是什么?仅仅是保存和提供配置信息吗?

 

转载请注明出处:http://www.cnblogs.com/linkstar/category/1027239.html

作者:LinkinStar

posted @ 2017-07-08 11:09  LinkinStar  阅读(1180)  评论(0编辑  收藏  举报