1. 程式人生 > 其它 >Mybatis中SqlSessionFactoryBuilder.build()原始碼分析

Mybatis中SqlSessionFactoryBuilder.build()原始碼分析

技術標籤:原始碼分析mybatisjava

文章目錄


一、SqlSessionFactoryBuilder.build()是幹什麼的?

SqlSessionFactoryBuilder.build() 是把我們的XML、Mapper、和配置檔案載入轉換成Bean的重要操作

二、原始碼分析

1.SqlSessionFactoryBuilder原始碼

看一下原始碼:

 public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    try {
    //1、解析配置檔案
      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
      return build(parser.parse());
    } catch (Exception
e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { reader.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } }

我們發現原始碼中又呼叫了 XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);去解析我們的配置檔案

那麼我們繼續去看一下這個方法:

2.XMLConfigBuilder解析配置檔案

解析流程:

1、建立好XMLConfigBuilder物件呼叫.parse()方法

我們看一下parse()方法

 public Configuration parse() {
 //XMLConfigBuilder只被解析一次
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

發現解析過程又呼叫了parseConfiguration()方法 我們繼續去看

2、檢查、封裝資料

private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));//封裝xml中propertise
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectionFactoryElement(root.evalNode("reflectionFactory"));
      settingsElement(root.evalNode("settings"));
      // read it after objectFactory and objectWrapperFactory issue #631
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));//封裝xml中mapper
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }

我們可以看到進行各種封裝,我們在XML中沒有配置的就不會封裝

3、封裝資料封裝到哪裡呢?

在這裡插入圖片描述
從原始碼可以看到組後資料是封裝到了我們的Configuration這個類中

4、分別解析到Configuration的哪些屬性中呢?

我們看一下最後一步怎麼解析Mapper的 也就是mapperElement(root.evalNode(“mappers”));這行程式碼
我們看核心原始碼:

 XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
            mapperParser.parse();

通過XMLMapperBuilder去讀取XML檔案然後去呼叫parse()封裝
對映檔案解析放到:loadedResources中

protected final Set<String> loadedResources = new HashSet<String>();

dao層Mapper介面解析到:mapperRegistry中

 protected MapperRegistry mapperRegistry = new MapperRegistry(this);

三、流程圖

在這裡插入圖片描述