spring和mybatis的dao层接口调用的原理探究

首先我们来看看mybatis简单的使用方法.
我们需要配置一个UserDao.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.xiaoyu.dao.UserDao">
    <select id="getUser" resultType="com.xiaoyu.entity.User">
        select
        a.id as id,
        a.name as name,
        from biz_user as a
        where a.id =#{userId}
    </select>

然后我们需要有个dao层接口,并使用spring的注解@Repository(高版本好像注解都不需要了)

@Repository
public class UserDao {
    User getUser(String userId);
}

这样我们就可以使用mybatis了,但是一方面我们会乐见于其使用的方便性,另一方面也可能会疑惑为什么我们的dao层(或mapper层)只需要写好一个接口就可以了,而完全没有任何实现.mybatis是如何去实现以及执行xml文件中的sql的了.我们接下来就研究下.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring.xml" })
public class TestService {

    @Autowired
    private UserDao userDao;

    @Test
    public void testUser() {
        User a = userDao.getUser("1");
        a.toString();
    }

}

我们写个简单的测试类并进行debug,可以看到代码会进入org.apache.ibatis.binding.MapperProxy类中调用方法.
顾名思义,这个MapperProxy是个代理类,并且实现了InvocationHandler.

public class MapperProxy<T> implements InvocationHandler, Serializable {}

其实从这里我们就可以想到,实现的原理就是用到了动态代理.也就是实际调用的是spring帮我们生成的代理对象.
好像就是这么回事?但是这样显得浅尝辄止,如何生成代理对象,以及生成了怎样的代理对象的才是我们应该知道的.
之前我一篇文章讲过spring扩展的问题.也同样适用于mybatis.我们在不深究之前可以大致想下处理流程.肯定是mybatis通过spring的扩展后,在启动的时候,spring按规则扫描mybatis的xml,并解析最后生成了一个代理对象存入spring中以供使用.所以我们来看下mybatis在spring启动的时候都做了什么吧.
在进行spring扩展的时候,我们需要创建spring.handlers文件,因此我们只需要在mybatis-spring-1.2.2.jar(当然我用的是这个版本的jar)中找到即可.

http\://mybatis.org/schema/mybatis-spring=org.mybatis.spring.config.NamespaceHandler

核心类已经列出来了,我们看看NamespaceHandler是怎么处理的吧.

public class NamespaceHandler extends NamespaceHandlerSupport {

  /**
   * {@inheritDoc}
   */
  public void init() {
    registerBeanDefinitionParser("scan", new MapperScannerBeanDefinitionParser(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值