MyBatis源码解析--加载流程(1)

本文将深入MyBatis的源码,解析其加载配置的完整流程。首先,它会加载mybatis-config.xml及mapper映射配置,转化为Configuration对象。接着,Configuration用于创建SqlSessionFactory。最后,通过SqlSessionFactory获取SqlSession执行数据库操作。文章从SqlSessionFactoryBuilder的build方法开始,逐步剖析XMLConfigBuilder如何读取和解析配置文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分析完11个提供支持的模块,接下来就完整地debug一遍加载的流程。
首先看下简单的流程:
1.初始化会加载mybatis-config.xml配置文件、mapper映射配置文件以及Mapper接口中的注解信息,这些信息都会形成相应的对象并保存到Configuration中。
2.利用Configuration创建SqlSessionFactory对象。
3.通过SqlSessionFactory创建SqlSession对象进行相关的数据库操作。

那么首先就从加载mybatis-config.xml文件开始:

//获得xml文件对应的reader
        Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

进入SqlSessionFactoryBuilder类的build方法

  public SqlSessionFactory build(Reader reader) {
   
   
    return build(reader, null, null);
  }
 public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
   
   
    try {
   
   
      //读取配置文件
      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
      return build(parser.parse());//解析配置文件得到configuration对象,并返回SqlSessionFactory
    } 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的构造函数来读取配置文件,在这之前先看看这个类的父类,即BaseBuilder

public abstract class BaseBuilder {
   
   
  //初始化过程的核心对象,xml配置文件的所有信息都会加载至此,全局唯一并单例
  protected final Configuration configuration;
  //TypeAlias别名信息记录在该对象
  protected final TypeAliasRegistry typeAliasRegistry;
  //TypeHandler别名信息记录在该对象
  protected final TypeHandlerRegistry typeHandlerRegistry;

  public BaseBuilder(Configuration configuration) {
   
   
    this.configuration = configuration;
    this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
    this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
  }

  public Configuration getConfiguration() {
   
   
    return configuration;
  }
//创建正则表达式
  protected Pattern parseExpression(String regex, String defaultValue) {
   
   
    return Pattern.compile(regex == null ? defaultValue : regex);
  }
//xxxValueOf方法都是将字符串转成相应的数据类型的值
  protected Boolean booleanValueOf(String value, Boolean defaultValue) {
   
   
    return value == null ? defaultValue : Boolean.valueOf(value);
  }

  protected Integer integerValueOf(String value, Integer defaultValue) {
   
   
    return value == null ? defaultValue : Integer.valueOf(value);
  }

  protected Set<String> stringSetValueOf(String value, String defaultValue) {
   
   
    value = (value == null ? defaultValue : value);
    return new HashSet<>(Arrays.asList(value.split(",")));
  }
//解析对应的JdbcType类型
  protected JdbcType resolveJdbcType(String alias) {
   
   
    if (alias == null) {
   
   
      return null;
    }
    try {
   
   
      return JdbcType.valueOf(alias);
    } catch (IllegalArgumentException e) {
   
   
      throw new BuilderException("Error resolving JdbcType. Cause: " + e, e);
    }
  }
//解析对应的ResultSetType
  protected ResultSetType resolveResultSetType(String alias) {
   
   
    if (alias == null) {
   
   
      return null;
    }
    try {
   
   
      return ResultSetType.valueOf(alias);
    } catch (IllegalArgumentException e) {
   
   
      throw new BuilderException("Error resolving ResultSetType. Cause: " + e, e);
    }
  }
//解析对应的ParameterMode类型
  protected ParameterMode resolveParameterMode(String alias) {
   
   
    if (alias == null) {
   
   
      return null;
    }
    try {
   
   
      return ParameterMode.valueOf(alias);
    } catch (IllegalArgumentException e) {
   
   
      throw new BuilderException("Error resolving ParameterMode. Cause: " + e, e);
    }
  }
//创建指定对象
  protected Object createInstance(String alias) {
   
   
    Class<?> clazz = resolveClass(alias);
    if (clazz == null) {
   
   
      return null;
    }
    try {
   
   
      return resolveClass(alias).newInstance();
    } catch (Exception e) {
   
   
      throw new BuilderException("Error creating instance. Cause: " + e, e);
    }
  }
//获得对应的类型
  protected <T> Class<? extends T> resolveClass(String alias) {
   
   
    if (alias == null) {
   
   
      return null;
    }
    try {
   
   
      return resolveAlias(alias);
    } catch (Exception e) {
   
   
      throw new BuilderException("Error resolving class. Cause: " + e, e);
    }
  }
//从typeHandlerRegistry中获得或者创建对应的TypeHandler对象
  protected TypeHandler<?> resolveTypeHandler(Class<?> javaType, String typeHandlerAlias) {
   
   
    if (typeHandlerAlias == null) {
   
   
      return null;
    }
    Class<?> type = resolveClass(typeHandlerAlias);
    if (type != null && !TypeHandler.class.isAssignableFrom(type)) {
   
   
      throw new BuilderException("Type " + type.getName() + " is not a valid TypeHandler because it does not implement TypeHandler interface");
    }
    @SuppressWarnings( "unchecked" ) // already verified it is a TypeHandler
    Class<? extends TypeHandler<?>> typeHandlerType = (Class<? extends TypeHandler<?>>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值