Mybatis源码分析_Mapper接口是如何实例化的 (2)

这篇具有很好参考价值的文章主要介绍了Mybatis源码分析_Mapper接口是如何实例化的 (2)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

我们在使用Spring+mybatis的时候,经常都是直接写一个接口和一个对应的 ***Mapper.xml文件,然后业务代码就可以直接注入这个接口了。它是如何做到的呢?

接口:

Mybatis源码分析_Mapper接口是如何实例化的 (2)

xml

Mybatis源码分析_Mapper接口是如何实例化的 (2) 

 想搞清楚这个问题,那还是要从Mybatis底层源码进行分析的。Mybatis是一个非常优先的框架,它大量的将所谓的设计模式运用到了底层源码当中。对于不太了解动态代理设计模式的,可以参考我的另外2篇博客

《大话设计模式》——读后感 (4)为别人做嫁衣?——动态代理模式(2)_chen_yao_kerr的博客-CSDN博客

Spring之AOP技术 (6)_chen_yao_kerr的博客-CSDN博客 

了解了动态代理技术,在Mybatis中,我们需要关注一个类 MapperProxyFactory。说的简单点,这个类就是负责根据接口与sqlSession来创建MapperProxy对象的  。

/*
 *    Copyright ${license.git.copyrightYears} the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.binding;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.ibatis.session.SqlSession;

/**
 *
 * 用于生成mapper接口动态代理的实例对象;
 * @author Lasse Voss
 */
public class MapperProxyFactory<T> {

  //mapper接口的class对象
  private final Class<T> mapperInterface;
  //key是mapper接口中的某个方法的method对象,value是对应的MapperMethod,MapperMethod对象不记录任何状态信息,所以它可以在多个代理对象之间共享
  private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<>();

  public MapperProxyFactory(Class<T> mapperInterface) {
    this.mapperInterface = mapperInterface;
  }

  public Class<T> getMapperInterface() {
    return mapperInterface;
  }

  public Map<Method, MapperMethod> getMethodCache() {
    return methodCache;
  }

  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
	//创建实现了mapper接口的动态代理对象
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  public T newInstance(SqlSession sqlSession) {
	 //每次调用都会创建新的MapperProxy对象
    final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

}

  

而MapperProxy干嘛的呢?其实,它就是实现了 InvocationHandler 接口的一个动态代理类.  我们之前学习动态代理的时候,不仅要给动态代理类传递接口信息,还要传递这个业务接口的具体实现类。这样,动态代理就可以代理具体的业务实现类了。

Mybatis源码分析_Mapper接口是如何实例化的 (2)

 文章来源地址https://www.toymoban.com/news/detail-499814.html

但是,在MapperProxy中,我们并没有这样的实现类,反而是直接持有了接口信息,思考一下为什么呢?

Mybatis源码分析_Mapper接口是如何实例化的 (2)

ok,言归正传。我们知道了MapperProxyFactory就是负责创建MapperProxy对象的,而这个对象是一个动态代理类,也就是说它可以根据  业务接口与sqlSession信息 生成一个代理类。

此处是不是非常的精妙,动态代理设计模式 与 简单工厂设计模式 的典型运用。

那么,整个流程是什么样的呢?

1.  就是sqlSession对象调用getMapper方法,最终进入了 MapperRegistry类的getMapper方法。

Mybatis源码分析_Mapper接口是如何实例化的 (2)

 

2.  在这个方法中,我们直接获取到MapperProxyFactory对象,并且直接调用 newInstance方法

3. 而MapperProxyFactory的newInstance方法,就是负责创建动态代理类的。

Mybatis源码分析_Mapper接口是如何实例化的 (2)

因此,mybatis的接口是无法被实例化的。实例化的是一个持有该接口信息的动态代理类。 

 

到了这里,关于Mybatis源码分析_Mapper接口是如何实例化的 (2)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • MyBatis源码剖析之Mapper代理方式细节

    MyBatis源码剖析之Mapper代理方式细节

    MyBatis是一个流行的Java持久层框架,它提供了多种方式来执行数据库操作,其中之一就是通过Mapper代理方式。通过Mapper代理方式,开发者可以编写接口,然后MyBatis会动态地生成接口的实现类,从而避免了繁琐的SQL映射配置。 具体代码如下: 思考⼀个问题,通常的Mapper接⼝我

    2024年02月14日
    浏览(11)
  • 『手撕 Mybatis 源码』06 - Mapper 代理方式初始化

    『手撕 Mybatis 源码』06 - Mapper 代理方式初始化

    首先修改一下 SqlSession 获取代理对象方式,即通过 getMapper() 来拿到动态代理对象 修改 sqlMapConfig.xml 引入配置文件的方式 把 UserMapper.xml 放到和 com.itheima.mapper.UserMapper 同一个目录,同时修改一下命名空间,然后就可以学习 MyBatis 的代理方式 问题 package name=“com.itheima.mapper”/

    2024年02月09日
    浏览(12)
  • 答疑解惑:解释在Mybatis-Spring下@Mapper与@MapperScan为何不能同时生效以及实现动态条件注册Mapper接口

    若项目中使用了@MapperScan注解后,则@Mapper注解不再生效 , 原因是:@MapperScan注解 会执行@Import(MapperScannerRegistrar.class),而MapperScannerRegistrar又会注册MapperScannerConfigurer BEAN,在MapperScannerConfigurer BEAN中会完成基于配置的包目录扫描注册所有mapper interface代理BEAN,而@Mapper注解的生效

    2024年02月11日
    浏览(10)
  • 使用MyBatis的mapper接口调用时有哪些要求?Mybatis 动态 sql 有什么用?执行原理?有哪些动态 sql?

    1. Mapper接口方法名和mapper.xml中定义的每个 sql的id相同 2.Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的 parameterType的类型相同 3.Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的 resultType的类型相同 4.Mapper.xml文件中的 namespace 即是 mapper接口的类路径 可以在

    2024年02月16日
    浏览(10)
  • mybatis中的mapper.xml中如何使用in方法

    mybatis中的mapper.xml中如何使用in方法

    提示:mapper.xml中如何使用in方法一般都是like或= 提示:使用foreach 注意,传入的参数是List ,如果传入的是array 则需要修改 collection部分定义为 collection=“array” 在MyBatis中使用in参数为集合时,需要使用到foreach标签。 下面详细介绍以下foreach标签的几个参数

    2024年02月15日
    浏览(9)
  • Postgresql源码(110)分析dsm动态共享内存分配与共享内存mq实例(dsm/toc接口备忘录)

    相关 《Postgresql源码(90)共享内存申请CreateSharedMemoryAndSemaphores》 《Linux内存映射函数mmap与匿名内存块》 《Linux共享内存与子进程继承》 用dsm框架的流程 评估共享内存大小:多次用shm_toc_estimate_chunk、shm_toc_estimate_keys向estimate中增加数据结构,最后用shm_toc_estimate得出刚才增加

    2024年02月14日
    浏览(12)
  • MyBatis中在Mapper中如何传递多个参数?(4种方法,超级详细)

    1、若Dao层函数有多个参数,那么其对应的xml中, #{0} 代表接收的是Dao层中的第一个参数, #{1} 代表Dao中的第二个参数,以此类推。 假设Dao层函数有两个参数,分别是int类型的id和String类型的name: 2、使用@Param注解,在Dao层函数的参数前面添加@Param注解来显式指定每个参数的名

    2024年02月05日
    浏览(9)
  • 【Redisson】分布式锁源码分析如何实现多个应用实例互斥

    lockName就是保存到Redis里面的key 直接进行构建方法里面的 super(commandExecutor, name); org.redisson.connection.ServiceManager : private final String id = UUID.randomUUID().toString(); 这个 id 就是 UUID : this.id = getServiceManager().getId(); 这个entryName通过UUID可以区分是哪个应用实例 entryName+threadId可以区分哪个应

    2024年02月11日
    浏览(9)
  • spring boot mybatis plus mapper如何自动注册到spring bean容器

    spring boot mybatis plus mapper如何自动注册到spring bean容器

    ##@Import(AutoConfiguredMapperScannerRegistrar.class) ##注册MapperScannerConfigurer ##MapperScannerConfigurer.postProcessBeanDefinitionRegistry方法扫描注册mapper ##找到mapper候选者 ##过滤mapper 类 候选者 ##BeanDefinitionHolder注册到spring 容器

    2024年01月17日
    浏览(10)
  • 解决Mybatis报错并分析原因:Invalid bound statement (not found): com.xxx.mapper.xxx

    解决Mybatis报错并分析原因:Invalid bound statement (not found): com.xxx.mapper.xxx

    今天同事在Mapper.xml自定义写了一个SQL,但是调用mapper的时候缺报错 我大概还原下场景 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.wyh.mapper.UserMapper.findByIDWYH 具体如下 一开始我觉得是不是没有扫描到mapper包,但是看了启动类,确实也配注解了呀 然后我又想 是

    2023年04月08日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包