mybatis源码分析(1)-----sqlSessionFactory创建

1. 首先了解一下mybatis,包含核心jar ,以及spring相关jar.

<!-- Mybatis相关组件 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.3.0</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.2.3</version>
</dependency>
  • 系列的文章也是mybatis 3.3.0和mybatis-spring1.2.3分析
  • mybatis jar包中只要包含mybaits的核心业务sqlsession,sqlsessionFactory,configuration
  • mybatis-spring 包中只要是和spring的相关集成,sqlSessionFactoryBean、transaction

2. 加载mybatis

本文以spring中加载mybatis为参考,由一下代码加载mybatis

<!-- 配置集成Mybatis -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation" value="classpath:/config/SQLMapConfig.xml" />
    <property name="mapperLocations"
        value="classpath*:com/chihiro/*/**/infra/mybatis/*Mapper.xml" />
</bean>
  • sqlSessionFactory接口(mybatis包核心接口)

  a、接口中有如下方法。子类中含有所有方法的实现

public interface SqlSessionFactory {
  SqlSession openSession();
  SqlSession openSession(boolean autoCommit);
  SqlSession openSession(Connection connection);
  SqlSession openSession(TransactionIsolationLevel level);
  SqlSession openSession(ExecutorType execType);
  SqlSession openSession(ExecutorType execType, boolean autoCommit);
  SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
  SqlSession openSession(ExecutorType execType, Connection connection);
  Configuration getConfiguration();
}

  b、接口的实现类,由sqlSessionFactoryBean产生的是默认的SqlSessionFactory(DefaultSqlSessionFactory)

  

  •  sqlSessionFactoryBean(mybatis-spring包下面的创建工厂的Bean,由spring 加载初始化)

  a、从上述mybais的加载,可以看到,构造sqlSessionFactoryBean之后给了默认的属性值,dataSource,configLocation,mapper

public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {

  private static final Log LOGGER = LogFactory.getLog(SqlSessionFactoryBean.class);

  private Resource configLocation;

  private Resource[] mapperLocations;

  private DataSource dataSource;

  //SqlSessionFactory 构造的协助类
  private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

  private SqlSessionFactory sqlSessionFactory;

  //创建sqlSessionFactory的方法体
  protected SqlSessionFactory buildSqlSessionFactory() throws IOException {
      Configuration configuration;
      XMLConfigBuilder xmlConfigBuilder = null;
      if (this.configLocation != null) {
    xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
    configuration = xmlConfigBuilder.getConfiguration();
    } else {
      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Property 'configLocation' not specified, using default MyBatis Configuration");
      }
      configuration = new Configuration();
      configuration.setVariables(this.configurationProperties);
    }
    ...
    return this.sqlSessionFactoryBuilder.build(configuration);
  }ss

  @Override
  public void afterPropertiesSet() throws Exception {
    notNull(dataSource, "Property 'dataSource' is required");
    notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
    //调用方法创建sqlSessionFactory
    this.sqlSessionFactory = buildSqlSessionFactory();
  }

  @Override
  public void onApplicationEvent(ApplicationEvent event) {
    if (failFast && event instanceof ContextRefreshedEvent) {
      // fail-fast -> check all statements are completed
      this.sqlSessionFactory.getConfiguration().getMappedStatementNames();
    }
  }

}
  1. 实现3个相关接口的作用

    FactoryBean接口:实现了该接口的类,在调用getBean(获取bean对象)的时候会返回该工厂返回的实例对象,也就是再调一次getObject方法返回工厂的实例。

    InitializingBean接口:实现了这个接口,那么当bean初始化的时候,spring就会调用该接口的实现类的afterPropertiesSet方法,去实现当spring初始化该Bean的时候所需要的逻辑。

    ApplicationListener接口:实现了该接口,如果注册了该监听的话,那么就可以了监听到Spring的一些事件,然后做相应的处理

     2.在bean初始化之后,可以看见,回调方法afterPropertiesSet,在里面构造configuration对象。以及产生sqlSession

    Configuration类:可以发现配置中读取configuration。(核心配置,关联mybatis整个生命周期)

      xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
      configuration = xmlConfigBuilder.getConfiguration();

    3.由sqlSessionFactoryBuild 构造sqlSessionFactory

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

}

4. 建设者模式

  生产sqlSessionFacoty 使用了建设者模式(Builder)。其构造过程主要注入了Configuration的实例对象,sqlSessionFactoryBuilder 扮演具体的建造者,configuration类主要负责建造细节的工作,sqlSessionFactory则是建造出来的产品

  •   总结

原文地址:https://www.cnblogs.com/chihirotan/p/6591425.html