在使用mybatis的时候,我们获取dao的方式一般是这样:

SqlSession session=sessionFactory.openSession();
PersonDao personDao=session.getMapper(PersonDao.class);

但在我们在spring的测试用例中使用mybatis的时候是这样使用的:

PersonDao personDao=(PersonDao) context.getBean("personDao");  

答案就在MapperFactoryBean这里。

Spring中获取的名为personDao的bean,其实是与单独使用MyBatis完成了一样的功能,那么我们可以推断,在bean的创建过程中一定是使用了MyBatis中的原生方法sqlSession.getMapper(PersonDao.class)进行了再一次封装。结合配置文件,我们把分析目标转向org.mybatis.Spring.mapper.MapperFactoryBean,初步推测其中的逻辑应该在此类中实现。查看的类层次结构图MapperFactoryBean也实现了FactoryBean和InitializingBean接口。

MapperFactoryBean初始化

MapperFactoryBean继承了SqlSessionDaoSupport,SqlSessionDaoSupport继承DaoSupport,DaoSupport实现了InitializingBean接口,让我们开看看它这接口的实现:

public final void afterPropertiesSet() throws IllegalArgumentException, BeanInitializationException {
// Let abstract subclasses check their configuration.
checkDaoConfig();
// Let concrete implementations initialize themselves.
try {
     //initDao()方法是模板方法,设计为留给子类做进一步逻辑处理。
initDao();
}
catch (Exception ex) {
throw new BeanInitializationException("Initialization of DAO failed", ex);
}
}

该方法主要包含两个功能,一个是调用checkDaoConfig()方法,一个是调用initDao方法。checkDaoConfig方法在DaoSupport是抽象方法,让我看看它在MapperFactoryBean的实现:

@Override
protected void checkDaoConfig() {
super.checkDaoConfig();
notNull(this.mapperInterface, "Property 'mapperInterface' is required");
Configuration configuration = getSqlSession().getConfiguration();
if (this.addToConfig && !configuration.hasMapper(this.mapperInterface)) {
try {
configuration.addMapper(this.mapperInterface);
} catch (Throwable t) {
logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", t);
throw new IllegalArgumentException(t);
} finally {
ErrorContext.instance().reset();
}
}
}

该方法主要是检查dao的配置,主要是检验sqlSessionFactory和mapperInterface属性不能为空,以及检测接口对于的映射文件是否存在,如果存在,那么就把它添加到configuration里面去,注册mapper。

在上面的函数中,configuration.addMapper(this.mapperInterface)其实就是将PersonDao注册到映射类型中,如果你可以保证这个接口一定存在对应的映射文件,那么其实这个验证并没有必要。但是,由于这个是我们自行决定的配置,无法保证这里配置的接口一定存在对应的映射文件,所以这里非常有必要进行验证。在执行此代码的时候,MyBatis会检查嵌入的映射接口是否存在对应的映射文件,如果没有回抛出异常,Spring正是在用这种方式来完成接口对应的映射文件存在性验证。

获取MapperFactoryBean的实例

public T getObject() throws Exception {
return getSqlSession().getMapper(this.mapperInterface);
}
在这里封装了getMapper操作,返回接口的实例,怪不得在Spring中使用MyBatis不用管理sqlSession了。所以对于上面的测试用例,Spring怎么封装了MyBatis,如何把sqlSessionFactory和sqlSession隐藏了起来,又怎么方便的获取dao接口实例,我们大概有了一个了解。

SpringMyBatis解析3-MapperFactoryBean的更多相关文章

  1. SpringMyBatis解析4-MapperScannerConfigurer

    如果有成百上千个dao接口呢,那我们岂不是要配置添加成百上千个bean,当然不是这样,spring还为MyBatis添加了拓展的功能,可以通过扫描包目录的方式,添加dao,让我看看具体使用和实现. & ...

  2. SpringMyBatis解析2-SqlSessionFactoryBean

    通过分析整合示例中的配置文件,我们可以知道配置的bean其实是成树状结构的,而在树的最顶层是类型为org.mybatis.spring.SqlSessionFactoryBean的bean,它将其他相 ...

  3. SpringMyBatis解析1-使用示例

    MyBatis使用介绍 MyBatis的详细使用介绍  http://www.cnblogs.com/xrq730/category/796495.html 建立PO public class Per ...

  4. mybatis源码学习(四)--springboot整合mybatis原理

    我们接下来说:springboot是如何和mybatis进行整合的 1.首先,springboot中使用mybatis需要用到mybatis-spring-boot-start,可以理解为mybati ...

  5. Mybatis的初始化和结合Spring Framework后初始化的源码探究

    带着下面的问题进行学习: (1)Mybatis 框架或 Spring Framework 框架对数据层 Mapper 接口做了代理,那是做了 JDK 动态代理还是 CGLIB 代理? (2)Mappe ...

  6. Mybaits 源码解析 (十)----- 全网最详细,没有之一:Spring-Mybatis框架使用与源码解析

    在前面几篇文章中我们主要分析了Mybatis的单独使用,在实际在常规项目开发中,大部分都会使用mybatis与Spring结合起来使用,毕竟现在不用Spring开发的项目实在太少了.本篇文章便来介绍下 ...

  7. SpringBoot 源码解析 (九)----- Spring Boot的核心能力 - 整合Mybatis

    本篇我们在SpringBoot中整合Mybatis这个orm框架,毕竟分析一下其自动配置的源码,我们先来回顾一下以前Spring中是如何整合Mybatis的,大家可以看看我这篇文章Mybaits 源码 ...

  8. spring--mybatis事务总结

    spring--事务原理.mybatis--MapperScannerConfigurer 和 mybatis--MapperProxy事务,最近想把spring mybatis中的事务和mapper ...

  9. Mybatis jpa mini 代码解析

    源码地址(git):https://github.com/LittleNewbie/mybatis-jpa 一.Mybatis简介 mybatis中文官方文档:http://www.mybatis.o ...

随机推荐

  1. codeforces 492C. Vanya and Exams 解题报告

    题目链接:http://codeforces.com/problemset/problem/492/C 题目意思:给出 3 个整数:n,  r,  avg.然后有 n 行,每行有两个数:第 i 行有 ...

  2. 【编程题目】有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配...

    37.(字符串)有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配,则两个字符串可以联接,问这 n 个字符串最多可以连成一个多长的字符串,如果出现循环, ...

  3. POJ 1753 Flip game ( 高斯消元枚举自由变量)

    题目链接 题意:给定一个4*4的矩阵,有两种颜色,每次反转一个颜色会反转他自身以及上下左右的颜色,问把他们全变成一种颜色的最少步数. 题解:4*4的矩阵打表可知一共有四个自由变元,枚举变元求最小解即可 ...

  4. sql 查询最近30分钟或者自定义时间数据

    ) FROM dual; 30分钟或者自定义

  5. iOS 十六进制和字符串转换

    NSString *dictString = [dict JSONFragment];//组合成的. dictString==={"content":"Sadgfdfg& ...

  6. iOS 短信分享 邮件分享

    本地调用短信分享. #import "shareViewController.h" @interface shareViewController (){ UIAlertView * ...

  7. Linux 查看 删除进程

    这东西,时间久不用总容易忘....记下来! 1. 在 LINUX 命令平台输入 1-2 个字符后按 Tab 键会自动补全后面的部分(前提是要有这个东西,例如在装了 tomcat 的前提下, 输入 to ...

  8. 趣味C++

        用三段 140 字符以内的代码生成一张 1024×1024 的图片 Kyle McCormick 在 StackExchange 上发起了一个叫做TweetableMathematical A ...

  9. c++11的初始化

    c++11 中类型初始更加方便 比如     vector<int> vec = {1,2,3}; vector<int> vec{1,2,3}; map<string, ...

  10. Android ANR分析(三)

    http://www.jianshu.com/p/8964812972be http://stackoverflow.com/questions/704311/android-how-do-i-inv ...