MyBatis源码骨架分析
(一)整体架构
设计模式:
采用外观模式(门面模式),由一个统一接口对外提供服务,客户端与子系统之间进行解耦,遵循了迪米特原则,对内封装了子系统复杂相互调用,对外只暴露必要的接口。
为什么要分层:
- 可维护性高,分工明确,系统清晰,维护方便。
- 方便团队开发、效率提升。
- 提高系统伸缩性和性能。
(二)日志模块
需求点
- 需要接入第三方的日志组件,统一日志级别。
- 按照第三方日志组件的优先级别进行自动扫描加载。
- 日志动态代理进行增强。
设计模式
适配器模式
代理模式
总结
日志模块实现采用适配器模式,日志组件(Target)、适配器以及统一接口(Log 接口)
定义清晰明确符合单一职责原则;同时,客户端在使用日志时,面向Log 接口编程,不需要
关心底层日志模块的实现,符合依赖倒转原则;最为重要的是,如果需要加入其他第三方日
志框架,只需要扩展新的模块满足新需求,而不需要修改原有代码,这又符合了开闭原则;
(三)数据源模块
需求点
- 组件都要实现DataSource接口
- MyBatis不但要集成第三方数据源组件,自己也提供了实现
- 数据源创建对象复杂,参数较多
设计模式
简单工厂
工厂模式
数据库连接池
两个ArrayList:空闲连接池、活跃连接池
获取连接、回收连接
(四)缓存模块
需求点
- 实现核心功能缓存数据的读写
- 还需要额外的附加功能:添加缓存清空策略(FIFO、LRU)、日志功能、序列化功能、阻塞功能等
- 附加功能能够以任意组合方式附加到核心功能之上
设计模式
装饰器模式
BlockingCache
通过锁粒度的控制来防止缓存雪崩问题
缓存使用HashMap会不会产生线程安全问题?
MyBatis缓存分为一级、二级缓存。在初始化二级缓存的时候,会默认加上SynchronizedCache增强,进行同步控制。一级缓存是线程独享的,不会出现线程安全问题。
CacheKey
update
equals
(五)反射模块
MetaObject
包装了5个核心反射类,对外的反射工具类,封装了对象的元信息。
(六)MyBatis流程分析
三个阶段
-
初始化阶段:
读取XML配置文件信息,创建配置对象Configuration,完成各个模块的初始化工作。 设计模式:建造者模式
-
代理封装阶段:
动态代理生成mapper接口的实现类。 设计模式:策略模式。SqlSessionFactory创建SqlSession时,TransactionFactory是典型的策略模式,通过在配置文件中灵活配置transactionManager。
-
数据访问阶段:
通过SqlSession完成SQL解析,参数映射、SQL执行、结果解析。 设计模式:模板模式。
(七)插件
设计模式
责任链模式