Mybatis源码解析之初始化分析
一、 Mybatis配置文件
configuation是mybatis配置文件的根节点。
configuration 配置 -properties 属性 -settings 设置 -typeAliases 类型别名 -typeHandlers 类型处理器 -objectFactory 对象工厂 -plugins 插件 -environments 环境 -environment 环境变量 -transactionManager 事务管理器 -dataSource 数据源 -databaseIdProvider 数据库厂商标识 -mappers 映射器
本文主要讲解源码,不对配置文件展开
二、配置文件解析过程
1. 初始化demo
下文代码是mybatis通过解析xml配置文件进行初始化的一个简单demo,后续我们将根据这个demo追踪mybatis源码的处理过程。
InputStream inputStream = Resources.getResourceAsStream("mybatis-coonfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession();
2. SqlSessionFactoryBuilder#build(InputStream, String. Properties)
SqlSessionFactoryBuilder的build(inputStream)方法通过调用同名的重载方法SqlSessionFactoryBuilder#build(InputStream, String. Properties)来生成需要的SqlSessionFacotry。
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { inputStream.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } } public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }
首先,通过XmlConfigBuilder解析配置文件,并得到configuration类对象。 然后根据configuration作为参数调用build得到所需的SqlSessionFactory,可以看到最终得到的SqlSessionFactory类型是DefaultSqlSessionFactory。
3. XMLConfigBuilder#parse()
public Configuration parse() { if (parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } parsed = true; parseConfiguration(parser.evalNode("/configuration")); return configuration; } private void parseConfiguration(XNode root) { try { //issue #117 read properties first propertiesElement(root.evalNode("properties")); Properties settings = settingsAsProperties(root.evalNode("settings")); 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); } }
可以看到,XMLConfigBuilder对xml配置文件中对configuration的子节点进行逐个解析。 以typeAliases为例,遍历typeAliases的子节点,根据配置情况将其加入到configuration对象中对应的typeAliasRegistry属性,其它节点的解析也类似。
private void typeAliasesElement(XNode parent) { if (parent != null) { for (XNode child : parent.getChildren()) { if ("package".equals(child.getName())) { String typeAliasPackage = child.getStringAttribute("name"); configuration.getTypeAliasRegistry().registerAliases(typeAliasPackage); } else { String alias = child.getStringAttribute("alias"); String type = child.getStringAttribute("type"); try { Class<?> clazz = Resources.classForName(type); if (alias == null) { typeAliasRegistry.registerAlias(clazz); } else { typeAliasRegistry.registerAlias(alias, clazz); } } catch (ClassNotFoundException e) { throw new BuilderException("Error registering typeAlias for '" + alias + "'. Cause: " + e, e); } } } } }
4. DefaultSqlSessionFactory#openSession()
@Override public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); } private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { final Environment environment = configuration.getEnvironment(); final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); final Executor executor = configuration.newExecutor(tx, execType); return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { closeTransaction(tx); // may have fetched a connection so lets call close() throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }
DefaultSqlSessionFactory#openSession()最终通过DefaultSqlSessionFactory#openSessionFromDataSource(ExecutorType, TransactionLevel, boolean)试下,可以看到最后获得的SqlSession类型是DefaultSqlSession,其中executor类型是SimpleExecutor。
到此这篇关于Mybatis源码解析之初始化分析的文章就介绍到这了,更多相关Mybatis初始化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
详解使用@RequestBody取POST方式的json字符串
这篇文章主要介绍了详解使用@RequestBody取POST方式的json字符串,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-12-12Spring MVC参数校验详解(关于`@RequestBody`返回`400`)
这篇文章主要介绍了Spring MVC参数校验的相关资料,主要是针对`@RequestBody`返回`400`的问题,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编来一起学习学习吧。2017-08-08java Callable接口和Future接口创建线程示例详解
这篇文章主要为大家介绍了java Callable接口和Future接口创建线程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-11-11
最新评论