一、背景
最近在工作之余,把开mybatis的源码看了下,决定自己手写个简单版的。实现核心的功能即可。写完之后,执行了一下,正巧在mybatis对Mapper接口的动态代理这个核心代码这边发现一个问题。正好再回头看了下jdk的动态代理发现问题所在。

二、问题
问题所在,当我用SqlSession.getMapper() 方法来获取Mapper的代理类的时候,发现这个代理对象所展示的toString()是个null。如下图

而debug了一下mybatis的源码发,发现是有值,并且的确是new 的MapperProxy类型的对象

三、回头看jdk动态代理
当我在排查问题的时候,无意中发现,在执行(T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);方法时,竟然会抛出 mapperProxy类的invoke方法中的异常,但是这个时候程序还没有走到任何代理的方法。
回头找了下之前学着写的动态代理的例子,并在invoke方法里面输出了method。如下:

启动main方法,发现打印的内容:

这时候才发现,在实例化代理类的时候,会调用一次invoke()方法,并且此时调用方法的method参数是Object.toString() 。看到这发现了两点

  1. invoke方法在实例化代理的时候会调用一次,如果这个方法有对全局的公共变量做修改的话,会存在隐患的问题
  2. 代理类的toString 最后出来的类的名称就是调用这个方法得到的。将代码中result输出就是对应的代理类。

四、发现并解决问题
回到自己的手写的mybatis源码中,自然就定位到了如下这个地方:

对比一下mybatis的源码

正是红框中的代码,自己手写的时候认为代理的方法的声明类都是定义的mapper接口,这边的判断其实没有必要,也走不到。然而从第三点中可以知道,在new 代理类的时候传入的Method为toString方法正好进了这个分支,并且调用了当前MapperProxy实例的toString方法,返回了代理类的名称,正式之前所缺失的。把这段代码加上就OK了

从Mybatis源码理解jdk动态代理默认调用invoke方法的更多相关文章

  1. mybatis源码阅读(动态代理)

    这一篇文章主要是记录Mybatis的动态代理学习成果,如果对源码感兴趣,可以看一下上篇文章  https://www.cnblogs.com/ChoviWu/p/10118051.html 阅读本篇的 ...

  2. mybatis源码学习: 动态代理的应用(慢慢改)

    动态代理概述 在学spring的时候知道使用动态代理实现aop,入门的列子:需要计算所有方法的调用时间.可以每个方法开始和结束都获取当前时间咋办呢.类似这样: long current=system. ...

  3. Mybatis源码解析(三) —— Mapper代理类的生成

    Mybatis源码解析(三) -- Mapper代理类的生成   在本系列第一篇文章已经讲述过在Mybatis-Spring项目中,是通过 MapperFactoryBean 的 getObject( ...

  4. Mybatis-简单基于源码了解获取动态代理对象

    这是我们要测试的代码 OderDao就是我们要需要获取的对象. 首先我们根据传入的参数,进入SqlSessionFactoryBuilder 中的对应的build 方法,第一步创键XMLConfigB ...

  5. 举例理解JDK动态代理

    JDK动态代理 说到java自带的动态代理api,肯定离不开反射.JDK的Proxy类实现动态代理最核心的方法: public static Object newProxyInstance(Class ...

  6. MyBatis之反射技术+JDK动态代理+cglib代理

    一.反射 引用百度百科说明: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功 ...

  7. Mybatis源码解析5—— 接口代理

    本篇文章,可乐将为大家介绍通过接口代理的方式去执行SQL操作.话不多说,直接上图: 其实无论哪种方式,我们最终是需要找到对应的 SQL 语句,接口代理的方式就是通过 [包名.方法名] 的方式,去找到 ...

  8. JDK动态代理

    一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...

  9. 深入浅出JDK动态代理(一)

    1.何为代理 代理,即代替主角完成一些额外的事情.例如,明星都有经纪人,明星参演电影之前,经纪人作为明星的代理人和出资方洽谈片酬.排期等,而真正参与拍戏的还是明星本人,明星拍完戏后,由经纪人代理明星去 ...

随机推荐

  1. python中的lambda函数用法

    例1:传入多个参数的lambda函数def sum(x,y): return x+y用lambda来实现:p = lambda x,y:x+yprint(4,6) 例2:传入一个参数的lambda函数 ...

  2. NGUI_Label

    五.Label是标签,一般是用来显示文字使用,当然NGUI的扩展性很强,可以通过添加相关的控件组成组合控件来进行复杂功能的使用. 1. 设置字体:可以设置NGUI中的字体,也可以设置Unity中的字体 ...

  3. [模拟赛] T2 不等数列

    Description 将1到n任意排列,然后在排列的每两个数之间根据他们的大小关系插入">"和"<".问在所有排列中,有多少个排列恰好有k个&qu ...

  4. Mycat 分片规则详解--范围取模分片

    实现方式:该算法先进行范围分片,计算出分片组,组内在取模 优点:综合了范围分片和取模分片的优点,分片组内使用取模可以保证组内的数据分布比较均匀,分片组之间采用范围分片可以兼顾范围分片的特点,事先规划好 ...

  5. vue技术解析六之生命周期函数

  6. 用Canvas写一个简单的游戏--别踩白块儿

    第一次写博客也不知怎么写,反正就按照我自己的想法来吧!怎么说呢?还是不要扯那些多余的话了,直接上正题吧! 第一次用canvas写游戏,所以挑个简单实现点的来干:别踩白块儿,其他那些怎么操作的那些就不用 ...

  7. 浅谈XAML控件

    在win10系统内简单使用了XAML控件,由于本人英语水平有限,在自己的摸索使用.分析代码以及翻译软件.搜索引擎.室友情的帮助下了解了控件的相关功能,下面简要对XAML控件提出几点建议: 1.Cale ...

  8. [poj2152]fire_树形dp

    fire poj-2152 题目大意:给出一颗树,给出两个相邻节点的距离,以及每个节点的接受范围,还有当前节点的代价.我们想要求出覆盖整个图的最小代价. 注释:一个点被覆盖,当且仅当该点有防火站或者这 ...

  9. 爬虫(scrapy中调试文件)

    在项目setting同级目录下创建py文件,代码如下: from scrapy.cmdline import execute import sys import os sys.path.append( ...

  10. 移动端H5地图离线瓦片方案

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 移动端的网速和流量耗费是移动开发必须考虑的两个点.常规的瓦片展 ...