Mybatis接口编程原理分析(三)
前面两篇博客Mybatis接口编程原理分析(一)和Mybatis接口编程原理分析(二)我们介绍了MapperProxyFactory、MapperProxy和MapperMethod的操作及源码分析,接下来我们介绍MapperRegistry
MapperRegistry:它是用来注册Mapper接口和获取登出代理类实例的工具类,它通过getMapper函数获得代理类和addMapper函数来注册代理类,
源码如下:
//这个类通过名字就可以看出 是用来注册Mapper接口与获取生成代理类实例的工具类 public class MapperRegistry { //全局配置文件对象 private final Configuration config; //一个HashMap Key是mapper的类型对象, Value是MapperProxyFactory对象 //这个MapperProxyFactory是创建Mapper代理对象的工厂 private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<Class<?>, MapperProxyFactory<?>>(); public MapperRegistry(Configuration config) { this.config = config; } //获取生成的代理对象 @SuppressWarnings("unchecked") public <T> T getMapper(Class<T> type, SqlSession sqlSession) { //通过Mapper的接口类型 去Map当中查找 如果为空就抛异常 final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type); if (mapperProxyFactory == null) { throw new BindingException("Type " + type + " is not known to the MapperRegistry."); } try { //否则创建一个当前接口的代理对象 并且传入sqlSession return mapperProxyFactory.newInstance(sqlSession); } catch (Exception e) { throw new BindingException("Error getting mapper instance. Cause: " + e, e); } } public <T> boolean hasMapper(Class<T> type) { return knownMappers.containsKey(type); } //注册Mapper接口 public <T> void addMapper(Class<T> type) { if (type.isInterface()) { if (hasMapper(type)) { throw new BindingException("Type " + type + " is already known to the MapperRegistry."); } boolean loadCompleted = false; try { knownMappers.put(type, new MapperProxyFactory<T>(type)); // It's important that the type is added before the parser is run // otherwise the binding may automatically be attempted by the // mapper parser. If the type is already known, it won't try. MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type); parser.parse(); loadCompleted = true; } finally { if (!loadCompleted) { knownMappers.remove(type); } } } } /** * @since 3.2.2 */ public Collection<Class<?>> getMappers() { return Collections.unmodifiableCollection(knownMappers.keySet()); } /** * @since 3.2.2 */ //注册Mapper接口 public void addMappers(String packageName, Class<?> superType) { ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>(); resolverUtil.find(new ResolverUtil.IsA(superType), packageName); Set<Class<? extends Class<?>>> mapperSet = resolverUtil.getClasses(); for (Class<?> mapperClass : mapperSet) { addMapper(mapperClass); } } /** * @since 3.2.2 */ //通过包名扫描下面所有接口 public void addMappers(String packageName) { addMappers(packageName, Object.class); } }
在DefaultSqlSession中通过getMapper函数从Configuration中获取代理类:
@Override public <T> T getMapper(Class<T> type) { return configuration.<T>getMapper(type, this); }
在Configuration类中通过getMapper从MapperRegistry来获取代理类
public <T> T getMapper(Class<T> type, SqlSession sqlSession) { return mapperRegistry.getMapper(type, sqlSession); }
这样就完成了mybatis接口编程的构造和调用的全部过程。
Mybatis接口编程原理分析(三)的更多相关文章
- Mybatis接口编程原理分析(二)
在上一篇博客中 Mybatis接口编程原理分析(一)中我们介绍了MapperProxyFactory和MapperProxy,接下来我们要介绍的是MapperMethod MapperMethod:它 ...
- Mybatis接口编程原理分析(一)
Mybatis接口编程示例 (1)首先定义接口编程需要的接口及其方法 public interface IUserMapper { public User getById(int id);//接口方法 ...
- MyBatis整合Spring原理分析
目录 MyBatis整合Spring原理分析 MapperScan的秘密 简单总结 假如不结合Spring框架,我们使用MyBatis时的一个典型使用方式如下: public class UserDa ...
- MyBatis的深入原理分析之1-架构设计以及实例分析
MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简单.优雅.本文主要讲述MyBatis的架构设计思路,并且讨论MyBatis的几个核心部件,然后结合一个select查询实例, ...
- Linux下Golang Socket编程原理分析与代码实现
在POSIX标准推出后,socket在各大主流OS平台上都得到了很好的支持.而Golang是自带Runtime的跨平台编程语言,Go中提供给开发者的Socket API是建立在操作系统原生Socket ...
- MyBatis框架及原理分析
MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 MyBatis的主要设计目的就 ...
- Mybatis插件原理分析(三)分页插件
在Mybatis中插件最经常使用的是作为分页插件,接下来我们通过实现Interceptor来完成一个分页插件. 虽然Mybatis也提供了分页操作,通过在sqlSession的接口函数中设置RowBo ...
- mybatis(一、原理,一对多,多对一查询)
MyBatis框架及原理分析 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 ...
- Spark原理分析目录
1 Spark原理分析 -- RDD的Partitioner原理分析 2 Spark原理分析 -- RDD的shuffle简介 3 Spark原理分析 -- RDD的shuffle框架的实现概要分析 ...
随机推荐
- 如何在Eclipse中快速添加main方法
在创建类时自动添加,只需要勾选"public static void main(String[] args)"
- String String Buffer String Builder
如题,在java中这是一个典型的问题. 在stackoverflow上已经有很多相似的问题被提问,并且有很多不正确或不完整的答案.如果你不往深处想,这是一个很简单的问题.但如果深入思考,它却很让人迷惑 ...
- nginx的yum安装,基本参数使用,编译参数说明和Nginx基本配置,模块安装
nginx的yum安装从nginx官网获取源 vim /etc/yum.repose.d/nginx.repo[nginx]name=nginx repobaseurl=http://nginx.or ...
- 继承自 DevExpress 17.2 的自定义控件如何在工具箱显示
最近把DevExpress版本从13.1升级到了17.2,结果发现继承自DevExpress的自定义控件居然在工具箱中消失了,弄了两天还是没有任何头绪,部分自定义Dev控件可以正常出现,但大部分自定义 ...
- 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- CustomYieldInstruction 自定义中断指令
ActionScript3脚本引擎为了方便热更新逻辑开发,提供的从脚本继承Unity类库功能在一些情况下可以提供开发的便利. 这次来建立一个示例,演示一下如何在脚本中自定义协程中断指令 Unity中的 ...
- 聊聊LightProbe原理实现以及对LightProbe数据的修改
0x00 前言 最近工作比较忙,所以文章已经很久没有更新了.这篇小文的主题也是在出差的高铁上想到,因为最近和一些朋友聊天,发现他们中很多人的项目中都使用了多个实时光源.细问之下主要是某些物体,例如角色 ...
- Hibernate异常之命名查询节点未找到
异常信息: java.lang.IllegalArgumentException: No query defined for that name [salaryEmps] at org.hiberna ...
- [总结] fhq_Treap 学习笔记
无旋版 $Treap$. 只需要两个操作即可达到 $splay$ 的所有功能 1.$split$ 它的主要思想就是把一个 $Treap$ 分成两个. $split$ 操作有两种类型,一种是按照权值分配 ...
- android 获取栈顶activty的方法总结(兼容API 5.0)
声明:本文为Dujinyang CSDN原创投稿文章,未经许可,禁止任何形式的转载. 最近5.0\6.0\7.0 安卓系统都陆续上岗了,兼容性和代码更新是个很头疼的问题,这次我们来说下TASK的基础和 ...
- [CSDN_Markdown] Markdown基本语法
简介 本文介绍Markdown的基本使用方法: 使用标题 加粗.斜体 分割线 列表 引用 我写博客一般将可以独立的内容分节,每一节有一个标题,标题的字体应该与正文的字体有点区别.两个相邻节之间使用分割 ...