首页 > 其他分享 >mybatis mapper接口实例化原理

mybatis mapper接口实例化原理

时间:2023-08-04 13:22:04浏览次数:29  
标签:mapper Object 接口 实例 UserMapperExt mybatis 方法

 

 

 

面试题来了:“我们都知道mybatis的mapper接口是没有实现类的,在使用的时候你知道它是如何实例化的吗?”

懵逼的我:“知道啊,用的是jdk自带的动态代理;”;

饥渴的面试官:“嗯,没错,继续说,它底层做了哪些事情?”;

懵逼的我:“就是动态代理啊,还有啥?”

得意的面试官:“这样子啊,那你回去等消息吧~”

 

原理

    首先呢,mybatis的mapper接口确实是用jdk动态代理实现的,关键方法是这个newProxyInstance:

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h){
}

 这个方法有什么作用呢?  首先它除了能作为AOP动态代理实现之外,还能用来作为mybatis的mapper接口映射,先看看这个方法是怎么使用的

package com.proxy_2.proxy;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
/**
 * 生成mapper
 *
 * 面试官的问题:  既然myBatis的mapper映射是个接口,那么它是怎么实例化的呢?
 *  这个问题其实很好回答, 它就使用jdk自带的动态代理实现的,通过实现
 */
public class MapperMappingTest {
 
 
    public static void main(String[] args) {
 
        Class<UserMapperExt> userMapperClass = UserMapperExt.class;
 
        ExtInvokeHandler handler = new ExtInvokeHandler();
 
        // 关键方法 调用一个方法后获得了
        UserMapperExt mapper = (UserMapperExt) Proxy.newProxyInstance(userMapperClass.getClassLoader(), new Class[]{userMapperClass}, handler);
        int x = mapper.addUser("1", 1);
        System.out.println(x);
        System.out.println(mapper);
    }
}
 
/*
 * -使用JDK自带动态代理实例化mapper接口,实现了InvocationHandler接口的调用处理器对象
 *
 * */
 class ExtInvokeHandler implements InvocationHandler  {
 
    /// 只有执行mapper接口方法时才会走 invoke 方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 
        if(Object.class.equals(method.getDeclaringClass())){
            // 如果调用了 Object 的方法,使用当前类的方法;,因为 UserMapperExt 没有实例化,不能直接调用UserMapperExt里的方法;
            return method.invoke(this,args);
        }
        // 不管走mapper的哪个方法,返回值都是 1 ,入股类型不匹配则会抛出异常
        return 1;
    }
}
 
// mapper 接口
interface UserMapperExt {
    //添加用户方法
    public int addUser(String name, int age);
}
 

 

从上面的代码可以看到,当我们调用 Proxy.newProxyInstance() 方法时,它并没有去实例化 UserMapperExt 接口,而是将实现了 InvokeHandler 接口的ExtInvokeHandler类作为 UserMapperExt 的实例化对象;眼见为实,我们打个断点看一下

 

但是当我们调用 UserMapperExt.addUser() 方法的时候,因为这个方法已经在ExtInvokeHandler.invoke() 方法被拦截了,就会直接使用ExtInvokeHandler.invoke方法的返回值,而不会去走真实的 UserMapperExt.addUser() 方法;

 

 

mybatis 映射执行流程图

 

转载:https://blog.csdn.net/qq_27184497/article/details/117398441 

 

标签:mapper,Object,接口,实例,UserMapperExt,mybatis,方法
From: https://www.cnblogs.com/porter/p/17605640.html

相关文章

  • DB2删除实例
    要删除实例:以具有root用户权限的用户身份登录。可选:如果您确定不再需要关联数据库中的数据,您可以在删除实例之前从系统中删除数据库文件或删除数据库。通过输入以下命令删除实例:DB2DIR/instance/db2idropInstName其中 DB2DIR是您在Db2数据库产品安装期间指定的位......
  • Mybatis-Plus 多数据源 @DS注解部分失效
    环境springboot+mybatis-plus在controller层一个request中有多个service调用保存接口,发现在mapper层上定义的@DS注解指定数据源部分指向了primary数据源。导致表找不到。处理猜测是不能走mybatis-plus生成的batchSave方法,将controller中多个service处理逻辑放到指定service中,......
  • application.yml文件中开启mybatis自动驼峰映射
    application.yml文件中开启mybatis自动驼峰映射configuration:#是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射map-underscore-to-camel-case:true如果不开启映射在使用BaseMapper和Iservice封装的方法时会报错如果在Mapper.xml文件中自......
  • Java面试题 P49:框架篇:MyBatis是否支持延迟加载?
         未配置延迟加载的执行结果: =========================================启用MyBatis延迟加载:     同样可以达到刚才的效果。   ......
  • Java面试题 P48:框架篇:MyBatis执行流程
         ......
  • SpringBoot+MyBatisPlus实现读写分离
    文章目录1、前言2、读写分离原理3、实现步骤3.1.主从复制搭建3.2.配置pom.xml3.3.配置数据源3.4.配置MyBatisPlus3.5.实现读写分离4、总结1、前言随着业务量的不断增长,数据库的读写压力也越来越大。为了解决这个问题,我们可以采用读写分离的方案来分担数据库的读写负载。本......
  • 三个实例演示 Java Thread Dump 日志分析
    jstackDump日志文件中的线程状态dump文件里,值得关注的线程状态有:死锁,Deadlock(重点关注) 执行中,Runnable  等待资源,Waitingoncondition(重点关注) Waitingonmonitorentry(重点关注)暂停,Suspended对象等待中,Object.wait()或TIMED_WAITING阻塞,Blocked(重点关注)......
  • 快餐数据分析--Python数据分析实例
    1、读取数据importpandasaspddf=pd.read_csv('快餐数据.tsv',sep='\t')print(df)2、查看基本信息查看前五条数据df.head()查看整体信息df.info()可以看到,一共有4622条数据,只有choice_description列有缺失值,item_price为object类型是因为价格前面有$符号。打印列名......
  • 【SpringBoot学习】6、SpringBoot 整合 Mybatis 逆向工程和整合 Mybatis
    mybatis逆向工程使用方法springboot整合mybtis逆向工程,我使用的是idea,springboot,maven,eclipse的同理。1、添加所需插件和jar包<plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><dep......
  • Mybatis-Plus代码生成器的使用
    通常我们在做项目的时候,要手动搭建项目的结构,如controller,service,mapper,entity,是不是很麻烦,特别是数据库表特别多时,现在介绍一下使用MybatisPlus时怎么自动生成这些代码。首先要在项目的pom.xml里引入必要的依赖,如下:<dependency><groupId>com.baomidou</groupId><ar......