【12.MyBatis源码剖析与架构实战】4.MapperProxy源码剖析
MyBatis MapperProxy 源码深度剖析MapperProxy是 MyBatis 中 Mapper 接口动态代理的核心实现类。它通过 JDK 动态代理拦截对 Mapper 接口方法的调用,将方法调用转换为对SqlSession的数据库操作(如查询、插入、更新、删除),同时处理方法返回值、参数映射、分页等细节。一、MapperProxy 的定位MyBatis 允许开发者只定义 Mapper 接口(如UserMapper),而不需要编写实现类。这得益于MapperProxy在运行时为接口生成代理对象,当调用接口方法时,代理逻辑会根据方法签名、参数以及 XML 或注解中定义的 SQL 语句,自动执行相应的数据库操作。相关类结构:MapperProxy:实现InvocationHandler,负责拦截方法调用。MapperProxyFactory:为每个 Mapper 接口创建MapperProxy实例,并生成代理对象。MapperMethod:封装了 Mapper 接口中某个具体方法的详细信息,包括 SQL 命令类型、返回值类型、参数解析等。二、MapperProxyFactory:代理对象的工厂在 MyBatis 初始化阶段,Configuration会为每个 Mapper 接口创建一个MapperProxyFactory实例,并缓存在MapperRegistry中。publicclassMapperProxyFactoryT{privatefinalClassTmapperInterface;privatefinalMapMethod,MapperMethodmethodCache=newConcurrentHashMap();publicMapperProxyFactory(ClassTmapperInterface){this.mapperInterface=mapperInterface;}@SuppressWarnings("unchecked")protectedTnewInstance(MapperProxyTmapperProxy){// 使用 JDK 动态代理生成代理对象return(T)Proxy.newProxyInstance(mapperInterface.getClassLoader(),newClass[]{mapperInterface},mapperProxy);}publicTnewInstance(SqlSessionsqlSession){finalMapperProxyTmapperProxy=newMapperProxy(sqlSession,mapperInterface,methodCache);returnnewInstance(mapperProxy);}}关键点:每个 Mapper 接口对应一个MapperProxyFactory。methodCache用于缓存MapperMethod对象,避免每次调用都解析方法签名(性能优化)。newInstance(SqlSession sqlSession)创建MapperProxy并生成代理对象。三、MapperProxy 源码分析MapperProxy实现了InvocationHandler,核心方法为invoke。publicclassMapperProxyTimplementsInvocationHandler,Serializable{privatestaticfinallongserialVersionUID=-6424540398559729838L;privatefinalSqlSessionsqlSession;privatefinalClassTmapperInterface;privatefinalMapMethod,MapperMethodmethodCache;publicMapperProxy(SqlSessionsqlSession,ClassTmapperInterface,MapMethod,