MyBatis源码解析(三):初始化SqlSession 电玩女神 2022-02-26 13:50 252阅读 0赞 前言:在[MyBatis源码解析(二):初始化SqlSessionFactory][MyBatis_SqlSessionFactory]中,已经成功解析XML配置文件,并初始化SqlSessionFactory;这一篇将对 SqlSessionFactory.openSession() 进行解析 一,SqlSessionFactory.openSession() 执行流程 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTE5NzYzODg_size_16_color_FFFFFF_t_70][] 二,初始化步骤 1,触发 openSession(),内部调用 openSessionFromDataSource() 完成初始化动作 public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); } private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { // 从Configuration中获取Environment配置信息 final Environment environment = configuration.getEnvironment(); // 从Environment配置信息获取事务工厂 final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); // 初始化事务, 此时事务持有dataSource对象 tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); // 初始化Executor, Executor通过Transaction间接持有DataSource对象 final Executor executor = configuration.newExecutor(tx, execType); // 初始化SqlSession对象, SqlSession持有configuration和executor引用 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(); } } 2,初始化数据库事务 -- JdbcTransactionFactory.newTransaction public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) { // 此时数据库事务持有DataSource信息 return new JdbcTransaction(ds, level, autoCommit); } 3,初始化 Executor 执行对象 -- Configuration.newExecutor \* ExecuteType配置信息和CacheEnabled配置信息官网解释 ![20190329235618512.png][] ![2019032923563271.png][] \* 初始化Executor方法;在开启缓存处理的情况下,注意此处通过装饰者模式对 SimpleExecutor 进行了二次装饰 CachingExecutor public Executor newExecutor(Transaction transaction, ExecutorType executorType) { // executorType如果未配置, 默认为Simple executorType = executorType == null ? defaultExecutorType : executorType; executorType = executorType == null ? ExecutorType.SIMPLE : executorType; Executor executor; if (ExecutorType.BATCH == executorType) { executor = new BatchExecutor(this, transaction); } else if (ExecutorType.REUSE == executorType) { executor = new ReuseExecutor(this, transaction); } else { executor = new SimpleExecutor(this, transaction); } // 未配置默认开启 if (cacheEnabled) { executor = new CachingExecutor(executor); } // 通过拦截器加载plugin, 返回对象为代理对象 executor = (Executor) interceptorChain.pluginAll(executor); return executor; } \* Executor 初始化时, 关联加载 Plugin 插件,并生成Executor代理对象,此处注意:代理对象可以被再次代理 public Object pluginAll(Object target) { // 此处遍历Plugins标签内所有Plugin进行加载 // 通过代理对象再代理模式, 保证每一个拦截器都能被执行 // 此处注意点 : 代理对象可以被再次代理 for (Interceptor interceptor : interceptors) { target = interceptor.plugin(target); } return target; } \* 生成 Executor 对象的代理对象,如存在多个,则后续传入的对象已经是代理对象,类似装饰者模式方式 public static Object wrap(Object target, Interceptor interceptor) { Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor); Class<?> type = target.getClass(); Class<?>[] interfaces = getAllInterfaces(type, signatureMap); // 存在有效插件 if (interfaces.length > 0) { // 对target即executor进行代理 // 外部循环调用, 则此时executor对象可能已经是代理对象 // 允许对代理对象再次进行代理 // 最终执行时, 装箱代理, 拆箱调用, 类似装饰者模式一层层进行处理 return Proxy.newProxyInstance( type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)); } return target; } 4,初始化SqlSession成功,获取的 SqlSession 为 DefaultSqlSession,此时 SqlSession 持有配置对象 Configuration,执行对象 CachingExecetor,已经持有 DataSource 配置的数据库事务对象 Transaction SqlSession sqlSession = sqlSessionFactory.openSession(); [MyBatis_SqlSessionFactory]: https://mp.csdn.net/postedit/88903330 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTE5NzYzODg_size_16_color_FFFFFF_t_70]: /images/20220226/0620ec05bbd3413bb994ab209943dfb8.png [20190329235618512.png]: /images/20220226/16989a43e8814384a7e8bfbe26638043.png [2019032923563271.png]: /images/20220226/2959f4b7dbbd4e7aa8bfa0411ee3a643.png
还没有评论,来说两句吧...