MyBatis Initialization Flow: From Configuration Loading to SqlSession Creation

Before executing SQL operations, MyBatis requires initialization: loading configuration resources, parsing them into an internal representation, and finally producing a SqlSession instance. This process involves three key stages:

  1. Obtaining a configuration InputStream via Resources.getResourceAsStream()
  2. Building a SqlSessionFactory using SqlSessionFactoryBuilder.build()
  3. Creating a SqlSession via SqlSessionFactory.openSession()

The typical bootstrap sequence looks like this:

InputStream configStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(configStream);
SqlSession session = factory.openSession();

  1. How Resources.getResourceAsStream() Resolves Configuration Files

This utility method abstracts classloader-aware resource resolution. It attempts to locate the specified file across multiple classloader contexts in a prioritized order.

Internally, it delegates to a ClassLoaderWrapper, which aggregates several candidate loaders:

  • The explicitly passed ClassLoader (if non-null)
  • The default loader configured in Resources
  • The current thread’s context classloader
  • The classloader that loaded the Resources class itself
  • The system classloader

The wrapper iterates through this list, invoking getResourceAsStream(resource) on each until one returns a non-null stream. If the initial lookup fails and the path lacks a leading slash, it retries with "/" + resource.

Under the hood, each ClassLoader resolves the resource by converting it to a URL (via getResource()) and opening its stream (url.openStream()). The URL resolution follows the delegation model—first consulting parent loaders, then falling back to the bootstrap classpath (e.g., sun.misc.Launcher.getBootstrapClassPath()) and finally custom findResource() implementations.

  1. Parsing Configuration and Building SqlSessionFactory

The SqlSessionFactoryBuilder.build(InputStream) method orchestrates XML parsing and factory construction:

public SqlSessionFactory build(InputStream inputStream) {
  return build(inputStream, null, null);
}

public SqlSessionFactory build(InputStream inputStream, String env, Properties props) {
  XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, env, props);
  Configuration config = parser.parse();
  return build(config);
}

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

The XMLConfigBuilder parses the input stream into a Configuration object—populating settings, mappers, type aliases, plugins, and environment details. Once parsed, the builder wraps it in a DefaultSqlSessionFactory, which serves as the factory for session instances.

  1. Instantiating SqlSession from SqlSessionFactory

DefaultSqlSessionFactory.openSession() is a convenience method that delegates to openSessionFromDataSource(), specifying default execution behavior:

public SqlSession openSession() {
  return openSessionFromDataSource(
      configuration.getDefaultExecutorType(),
      null,
      false
  );
}

The core logic inside openSessionFromDataSource() includes:

  • Retrieving the Environment from Configuration
  • Instantiating a TransactionFactory based on the environment’s transaction manager type
  • Creating a Transaction bound to the data source, isolation level, and auto-commit settting
  • Constructing an Executor (e.g., SimpleExecutor, CachingExecutor) wrapped around the transaction
  • Returning a new DefaultSqlSession initialized with the configuration, executor, and auto-commit flag

This final step yields a fully functional SqlSession ready for CRUD operations, statement execution, and transaction control.

Tags: MyBatis sqlsession configuration-parsing ClassLoader xml-parsing

Posted on Fri, 16 Oct 2026 16:32:12 +0000 by router