mybatis mapper接口实例化原理
面试题来了:“我们都知道mybatis的mapper接口是没有实现类的,在使用的时候你知道它是如何实例化的吗?”
懵逼的我:“知道啊,用的是jdk自带的动态代理;”;
饥渴的面试官:“嗯,没错,继续说,它底层做了哪些事情?”;
懵逼的我:“就是动态代理啊,还有啥?”
得意的面试官:“这样子啊,那你回去等消息吧~”
原理
首先呢,mybatis的mapper接口确实是用jdk动态代理实现的,关键方法是这个newProxyInstance:
1 2 3 4 | 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南