Mybatis-spring 原理之 Mapperbean自动注入,mapper代理

本文探讨了在Mybatis-spring整合中,为何业务代码能直接调用未实现的接口方法。关键在于Spring的bean注入和动态代理机制。详细解析了Spring如何注入mapperBean,以及动态代理的创建过程,包括getMapper、addMapper和MappedStatement的角色。文章旨在揭秘Mybatis-spring如何实现Mapper接口的代理,以便于理解框架内部工作原理。
摘要由CSDN通过智能技术生成

1. 问题背景

使用mybatis + mapper配置的方式,在业务代码中

1.1 定义,自动导入Dao类

 @Resource
    private ViewpointPkgDao viewpointPkgDao;

1.2 使用,直接使用ViewpointPkgdao.listViewpointPkg()

// 单独在粉丝端过滤出没有关联组合code的观点包
List<ViewpointPkgFullInfo> noRelated = viewpointPkgDao.listViewpointPkg(qryForm).stream().
                    filter(vp -> StringUtil.isEmpty(vp.getCombiCode())).collect(Collectors.toList());
viewpointPkgList = CommonTool.genCopyBeanList(noRelated,

listViewpointPkg方法在ViewpointPkgdaoMapper.xml中有定义,即sql实现了该方法,指定了出参和入参,

<select id="listViewpointPkg"
            parameterType="xxxx.ViewpointPkgDataBaseQryForm"
            resultType="xxxxx.ViewpointPkgFullInfo">
        SELECT
            a.viewpoint_pkg_id AS viewpointPkgId,
            a.name,
            a.broker_id AS brokerId,
            a.broker_manager_id AS brokerManagerId,
            a.status,
            ...
        FROM
            <include refid="filterViewpointPkgFullInfoSql"/>
        <if test="orderBySql != null">
            ORDER BY ${orderBySql}
        </if>
        <if test="limitSql != null">
            LIMIT ${limitSql}
        </if>
    </select>

为啥,通过MyBatis对ViewpointPkgDaomapper.xml自动生成工具代码后,本质MyBatis和我们都没有实现ViewpointPkgDao接口,业务代码中能直接调用ViewpointPkgDao接口的相关方法?

答案是: spring容器bean注入+动态代理

从调试结果也证明了这一动态代理猜想,org.apache.ibatis.binding.MapperProxy@6304a864
在这里插入图片描述

2. spring 注入mapperBean

https://zhuanlan.zhihu.com/p/196744982
在这里插入图片描述

3. 动态代理

3.1 定义

org.apache.ibatis.binding.MapperProxy

// 实现了 InvocationHandler接口??有何用
public class MapperProxy<T> implements InvocationHandler, Serializable {
   

  private final SqlSession sqlSession;
  private final Class<T> mapperInterface;
  private final Map<Method, MapperMethod> methodCache;
  
  // 构造,传入了 SqlSession,说明每个session中的代理对象的不同的!
  public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
   
    this.sqlSession = sqlSession;
    this.mapperInterface = mapperInterface;
    this.methodCache = methodCache;
  }

3.2 被创建

org.apache.ibatis.binding.MapperProxyFactory#newInstance
通过mapper代理工厂创建mapper代理

  // jdk动态代理
  protected T newInstance(MapperProxy<T> mapperProxy) {
   
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] {
    mapperInterface },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值