mybatis源码解析(一)数据源的创建

Mybatis源码解析-数据源的创建
 
 
从demo出发,逐步调试
mybatis源码解析(一)数据源的创建
 
 
1)
String resource = "Configuration.xml";
reader = Resources.getResourceAsReader(resource);
根据资源名称获取资源,这里的reader是java原生提供的读取字符流的包装类,不做详述
 
2)
SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
根据上一步得到的配置文件的资源流,传入build方法
mybatis源码解析(一)数据源的创建
build方法有多个重载,具体逻辑流转到public SqlSessionFactory build(Reader reader, String environment, Properties properties)方法中在这个方法中,先根据传入的参数创建一个XMLConfigBuilder类用于解析xml配置文件,具体的解析过程在parse方法,我们先看一下XMLConfigBuilder类实例化时初始化了哪些变量,进入到XMLConfigBuilder的构造函数
mybatis源码解析(一)数据源的创建
具体的构造过程在 私有构造方法XMLConfigBuilder(XPathParser parser, String environment, Properties props)中,该方法先调用父类BaseBuild的构造,其中将Configuration类中的别名注册器传播给父类BaseBuilder (这里记录一下,后面会用到)。具体如下
mybatis源码解析(一)数据源的创建
传入一个用于抽象配置的类Configuration,设置异常上下文,设置未被解析(只能被解析一次)、环境Environment和解析器 parse(后面的解析过程需要用到)
后面就是具体的解析过程,在parse()方法中
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
判断是否被解析过,若已经被解析,则抛出异常Each XMLConfigBuilder can only be used once
 
通过调用parse的evalNode解析xml文件中的/configuration标签,因为在创建parse属性是传入了第一步得到的xml资源对象reader,在他的构造函数中将reader转化为document对象,所以parse可以直接解析我们的xml配置文件configuration标签,以下是解析configuration的逻辑
mybatis源码解析(一)数据源的创建
解析器的解析逻辑代理给xpath来解析(应该是使用xml四种解析方式中的sax),返回XNode对象传入parseConfiguration(XNode root)方法,去处理configuration标签的数据,parseConfiguration(XNode root)方法负责处理configuration标签的各个子标签,如下
mybatis源码解析(一)数据源的创建mybatis源码解析(一)数据源的创建
对比一下我们的xml配置文件,我们着重看一下数据源的创建
 
在environment标签的解析方法中,这两行主要是数据源的创建,先创建数据源工厂,再使用工厂方法获得数据源对象
 
mybatis源码解析(一)数据源的创建
获得xml文件中配置的dataSource标签的属性type来解析处具体的数据源工厂类,并使用反射获得构造函数,实例化一个工厂对象。此处配置为POOLED (池化),再讲dataSource的子标签,如驱动类、用户名、密码等转化为Properties类传入得到的数据源工厂对象中。根据type解析数据源工厂类是根据前面new出来的Configuration类在初始化时注册的一系列别名,在
mybatis源码解析(一)数据源的创建
XMLConfigBuilder初始化时将Configuration传给父类BaseBuilder,并且在父类构造中将别名注册器传播给自身属性,所以在解析数据源工厂类时使用的是是Configuration中别名注册器注册的PooledDataSourceFactory类
最后再通过工厂类获得数据源