第3篇 SqlSessionFactory创建过程

1.载入配置文件

String resource = "com/gupaoedu/lsj/mybatis/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);

2.构建SqlSessionFactory

SqlSessionFactoryBuilder负责构建

 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

2.1 接受输入流

1、字节输入流build方法有四个:
image.png

2、 字符输入流build方法有四个:
image.png

2.1 输入流解析成Configuration

image.png

3.Configuration构建

3.1 创建XMLConfigBuilder对象

该方法里,又创建了XPathParser对象,传入配置文件信息属性文件信息、XMLMapperEntityResolver对象等。然后给它的属性赋值。
将创建好的XPathParser 对象传递给XMLConfigBuilder

public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
    this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
  }
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    super(new Configuration()); // 调用父类BaseBuilder构造
    ErrorContext.instance().resource("SQL Mapper Configuration");
    this.configuration.setVariables(props);
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
  }

public class XPathParser {
  private Document document;  // 存放配置文件内容,
  private boolean validation;
  private EntityResolver entityResolver; // 默认实现是XMLMapperEntityResolver
  private Properties variables; // 属性文件
  private XPath xpath;
}

 public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {
    commonConstructor(validation, variables, entityResolver);
    // 将配置文件解析成document 
    this.document = createDocument(new InputSource(inputStream));
  }

3.2 Configuration实例化

XMLConfigBuilder构造函数中, super(new Configuration()),调用父类BaseBuilder构造,完成Configuration初始化。
Configuration()方法完成了typeAliasRegistry和languageRegistry的初始化注册。

public Configuration() {
    typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
    typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);

    typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
    typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
    typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);

    typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
    typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
    typeAliasRegistry.registerAlias("LRU", LruCache.class);
    typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
    typeAliasRegistry.registerAlias("WEAK", WeakCache.class);

    typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);

    typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
    typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);

    typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
    typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
    typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
    typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
    typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
    typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
    typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);

    typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
    typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);

    languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
    languageRegistry.register(RawLanguageDriver.class);
  }
 public BaseBuilder(Configuration configuration) {
    this.configuration = configuration;
    this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
    this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
  }

public class XMLConfigBuilder extends BaseBuilder {
  private boolean parsed;
  private XPathParser parser;
  private String environment;
  private ReflectorFactory localReflectorFactory = new DefaultReflectorFactory();
}
public abstract class BaseBuilder {
  protected final Configuration configuration;
  protected final TypeAliasRegistry typeAliasRegistry;
  protected final TypeHandlerRegistry typeHandlerRegistry;
}

3.2 解析配置文件

此处只是列出了parseConfiguration步骤,涉及到的元素。后面会有专门文章单独拆解每一个步骤的解析。

  public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
// 把配置文件顶层标签configuration,解析成XNode对象传入parseConfiguration方法
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

  private void parseConfiguration(XNode root) {
    try {

      Properties settings = settingsAsPropertiess(root.evalNode("settings"));
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      loadCustomVfs(settings);
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      settingsElement(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"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }

4.创建SqlSessionFactory

默认是DefaultSqlSessionFactory

 public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

public class DefaultSqlSessionFactory implements SqlSessionFactory {
// 配置文件最后解析成Configuration,然后存储在这里
  private final Configuration configuration;

   public DefaultSqlSessionFactory(Configuration configuration) {
    this.configuration = configuration;
  }
}

总结:本文只是对SqlSessionFactory创建过程做了简要的分析,目的让大家大致了解实现的步骤,所以粒度很粗。过程和结构了解了,再去向下分析细节才更有意义。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容