Mybatis源码分析-getMapper()源码分析

本文探讨了MyBatis如何通过动态代理技术为未实现的接口生成代理类,并执行其方法。通过源码分析,解释了接口没有实现类也能执行方法的原因,并讨论了不同方法在相同或不同Mapper上的执行路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、接口没有实现类能执行方法吗?

答案:能!
我们看一下这段代码

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
     //6、执行SQL语句
    List<User> users = mapper.selectAllUser(new Random().nextInt());

我们都知道在Mybatis中调用SqlSession的GetMapper方法就可以拿到我们的Mapper,然后调用Mapper中的方法就能去查询数据库得到数据。
我们可以看到我们的Mapper并没有实现类啊,为什么能执行方法体呢?

二、动态代理

可想而知是我们的Mybatis通过动态代理技术帮我们生成的代理类去执行我们的方法

三、源码分析

1. GetMapper()方法

 public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
 //初始化代理工厂
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
    
    if (mapperProxyFactory == null) {
      throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    }
    try {z
    // 返回我们生成的代理类
      return mapperProxyFactory.newInstance(sqlSession);
    } catch (Exception e) {
      throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    }
  }

2.newInstance()方法

  public T newInstance(SqlSession sqlSession) {
    final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
  //生成代理类并返回,
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

四、问题思考

1、Mybatis中一个接口如果有多个方法的话会走同一个代理类吗?

newInstance(SqlSession sqlSession)
通过源码我们可以看出来 这个跟sqlSession有关系
1.如果用getMapper取同一个Mapper同一个Mapper执行不同方法会走同一个invok方法
2.不同Mapper走不同的invok方法

Mybatis基于多个不同的接口声带代理类,不同的接口肯定不同的invok,相同的接口,不同方法肯定会执行统一哥invoke方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值