MyBatis源码分析(八):设计模式
Mybatis中用到的设计模式
1. 建造者(Builder)模式:
表示一个类的构建与类的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂的对象,他只允许用户只通过指定复杂对象的类型和内容就可以构建它们。
比如SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、XMLStatementBuilder、CacheBuilder。
SqlSessionFactoryBuilder为例。模式结构:SqlSessionFactoryBuilder为具体的建造者,他没有抽象建造者父类,因为只有它一个,构建完生命周期也结束了,SqlSessionFactoryBuilder依赖于SqlSessionFactory,SqlSessionFactory的构建交给SqlSessionFactoryBuilder,表示SqlSessionFactory类的构建(SqlSessionFactoryBuilder)与SqlSessionFactory类的表示分离。
2. 工厂方法模式:
核心的工厂类不再负责所有产品的创建,而是将创建的工作交给产品接口的子类去做,这个工厂类必须为其实现接口,而不负责某一类产品实例化这种细节。
比如SqlSessionFactory、MapperProxyFactory、ObjectFactory。
以构建SqlSessionFactory为例。模式结构为:具体工厂DefaultSqlSessionFactory生产具体产品DefaultSqlSession ,具体产品有一抽象产品接口SqlSession,DefaultSqlSessionFactory有一个抽象工厂接口SqlSessionFactory
Mapper的配置映射
3. 装饰者模式:
动态地给一个对象增加一些额外的职责,装饰模式比实现子类效率会高,可以称为包装器。
比如说Mybatis的执行器。模式结构:Executer(抽象构件),CachingExecutor(具体构件),BaseExecutor(抽象装饰类),SimpleExecutor 和 ReuseExecutor(具体装饰类)。
还有Mybatis的缓存Cache,Cache (组件对象的接口),PerpetualCache(具体组件,是我们需要装饰的对象),LruCache等其他类(具体装饰类,被装饰的对象)
org.apache.ibatis.cache包结构:
4. 适配器模式:
将一个类的接口转换成希望的另外一个接口。
最常见于logger日志那一块。
模式结构:Log就是要转化的目标接口(Target ),各个子包下的实现类就是各种日志框架的适配器(Adapter),在这个Mybatis包之外的日志框架的Logger就是要适配的类(Adaptee)
5. 代理模式:
JDK的动态代理,详见 探索Mybatis之JDK动态代理:探究Proxy.newProxyInstance()生成的代理类解析
6. 模板模式:
定义一个抽象类,里面有一系列基本操作,这些操作可以是具体的,也可以是抽象的,每一个基本步骤对应算法的一个步骤,再其子类中可以重定义并实现一个算法的各个步骤。
比如说Myabtis中抽象的执行器BaseExecutor。模式结构:抽象类BaseExecutor,具体子类主要是SimpleExecutor、ReuseExecutor、BatchExecutor这三个。
7. 单例模式:
保证一个类仅有一个实例。
比如说ErrorContext、LoggerFactory
ErrorContext:
LogFactory:
LogFactory是用自己的class和要被适配的日志类的class,通过setImplementation用Construction构建起来的一个单例logConstructor,tryImplementation保证它是单例的。
1 private static void tryImplementation(Runnable runnable) {
2 if (logConstructor == null) {
3 try {
4 runnable.run();
5 } catch (Throwable t) {
6 // ignore
7 }
8 }
9 }
10
11 private static void setImplementation(Class<? extends Log> implClass) {
12 try {
13 Constructor<? extends Log> candidate = implClass.getConstructor(String.class);
14 Log log = candidate.newInstance(LogFactory.class.getName());
15 if (log.isDebugEnabled()) {
16 log.debug("Logging initialized using '" + implClass + "' adapter.");
17 }
18 logConstructor = candidate;
19 } catch (Throwable t) {
20 throw new LogException("Error setting Log implementation. }
8. 组合模式
9. 迭代器模式
(未完待续)
MyBatis源码分析(八):设计模式的更多相关文章
- MyBatis源码分析(4)—— Cache构建以及应用
@(MyBatis)[Cache] MyBatis源码分析--Cache构建以及应用 SqlSession使用缓存流程 如果开启了二级缓存,而Executor会使用CachingExecutor来装饰 ...
- MyBatis源码分析(2)—— Plugin原理
@(MyBatis)[Plugin] MyBatis源码分析--Plugin原理 Plugin原理 Plugin的实现采用了Java的动态代理,应用了责任链设计模式 InterceptorChain ...
- 【MyBatis源码分析】select源码分析及小结
示例代码 之前的文章说过,对于MyBatis来说insert.update.delete是一组的,因为对于MyBatis来说它们都是update:select是一组的,因为对于MyBatis来说它就是 ...
- Mybatis源码分析-BaseExecutor
根据前文Mybatis源码分析-SqlSessionTemplate的简单分析,对于SqlSession的CURD操作都需要经过Executor接口的update/query方法,本文将分析下Base ...
- Mybatis源码分析之Cache二级缓存原理 (五)
一:Cache类的介绍 讲解缓存之前我们需要先了解一下Cache接口以及实现MyBatis定义了一个org.apache.ibatis.cache.Cache接口作为其Cache提供者的SPI(Ser ...
- MyBatis源码分析-MyBatis初始化流程
MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...
- MyBatis源码分析-SQL语句执行的完整流程
MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...
- MyBatis源码分析(5)——内置DataSource实现
@(MyBatis)[DataSource] MyBatis源码分析(5)--内置DataSource实现 MyBatis内置了两个DataSource的实现:UnpooledDataSource,该 ...
- MyBatis源码分析(3)—— Cache接口以及实现
@(MyBatis)[Cache] MyBatis源码分析--Cache接口以及实现 Cache接口 MyBatis中的Cache以SPI实现,给需要集成其它Cache或者自定义Cache提供了接口. ...
- MyBatis源码分析之环境准备篇
前言 之前一段时间写了[Spring源码分析]系列的文章,感觉对Spring的原理及使用各方面都掌握了不少,趁热打铁,开始下一个系列的文章[MyBatis源码分析],在[MyBatis源码分析]文章的 ...
随机推荐
- 法术迸发(Spellburst)
描述 法术迸发 (EN:Spellburst ) 是一种在<通灵学园>中加入的关键字异能,在玩家打出一张法术牌后触发,只能触发一次. 若随从在法术结算过程中死亡,则不会触发效果 思路 首先 ...
- Sonarqube C# 配置资料整理
c#配置方式: http://www.cnblogs.com/CoderAyu/p/9416376.html http://www.cnblogs.com/jingridong/p/6513884.h ...
- 可选链运算符、空值合并运算符 --应用到vue项目
1.npm安装 npm install @babel/plugin-proposal-optional-chaining // 可选链运算符 ?. npm install @babel/plugin- ...
- WebView(网页视图)基本用法
资料来源于菜鸟教程 啊这官方文档居然失效了,打不开.那我们直接就看相关方法: WebChromeClient:辅助WebView处理Javascript的对话框.网站图标.网站title.加载进度等! ...
- 获取发布版SHA1和调试版SHA1
总结 调试版: 常见问题 | 高德地图API (amap.com) 发布版: 首先需要生成签名 Android Studio生成签名文件,自动签名,以及获取SHA1和MD5值_donkor_的博客-C ...
- vue报错 Uncaught TypeError: Cannot read property of null
有可能是点击a标签,但是a标签有click事件,未阻止默认事件导致报错,开始都看不出来是什么错误
- PHP获取当前网址路径
$_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'] // 获取来源 function ...
- Jmeter系列(15)- 常用断言之大小断言
大小断言 大小断言验证响应数据size大小,它的作用范围有主Sample与子Sample:适用场景,判断附件下载的大小,比如项目安装包 完整响应:全部响应信息 响应头:响应头信息,比如http协议的头 ...
- PC+PLC通过Modbus协议构建工控系统
一. 概述 工业设备采用HMI+PLC控制是比较常见的方案,随着工业自动化的要求越来越高,现在很多设备都要求接入企业MES系统,MES系统一般为WEB系统,接口形式大部分为HTTP协议,这种传统方案和 ...
- django 各项配置基本设置
setting中一些设置例子 mysql数据库连接设置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': ...