填坑之动态代理生成的代理类文件在哪?

初衷

最近想研究研究Mybatis源码,了解一下Mybatis的执行过程,从mybatis-config.xml配置文件开始,一直到Mybatis执行CRUD位置,中途出现很多疑惑,今天特记录一个!
Mybatis在执行CRUD前,会读取咱们的Mapper接口层,即Dao层,但我们写的时候只写了接口,缺没有写实现类,Mybatis是如何执行的呢,首先想到了动态代理,果不其然被我找到了:

public class MapperProxyFactory<T> {

  private final Class<T> mapperInterface;
  private final Map<Method, MapperMethodInvoker> methodCache = new ConcurrentHashMap<>();

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

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

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

  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
  	//就是在这里,使用了Proxy对象来生成代理类实体的
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  public T newInstance(SqlSession sqlSession) {
  	//这个是代理类实体对象的调用处理器,继承InvocationHandler
    final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

}

那么疑惑来了,生成的代理对象是什么样子的呢,文件又在哪呢?
其实吧,JDK动态代理实在JVM运行过程中生成代理对象的,所以当JVM没有运行时,是没有代理对象的,那么如何让其生成文件呢?介绍几个方法:

方法一

最方便最简单最直观的方式:`saveGeneratedFiles``,此方法只针对jdk动态代理
1. 在代码的启动入口(Main)加入如下代码,二选一:

//JDK1.8及以前的版本
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
 
//JDK1.8以后的版本
System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");

如图所示:
填坑之动态代理生成的代理类文件在哪?_第1张图片
2. 运行main方法
这就省了,要是这都不会,可以考虑改行了,哈哈哈
3. 寻找文件
项目根路径的同级目录,我的项目名称为bigdata,如图所示:
填坑之动态代理生成的代理类文件在哪?_第2张图片
注意:生成的路径一般为com\sun\proxy$Prroxy**.class
填坑之动态代理生成的代理类文件在哪?_第3张图片
4. 查看生成的文件
简单粗暴,直接将class文件拖拽到IDEA中,如下:
填坑之动态代理生成的代理类文件在哪?_第4张图片

画个重点:

  • 查清楚自己的JDK版本,不然再怎么操作也看不到!!!
  • Main方法中,Test的Junit单元测试中不会出现,不用试了,我就是调到这个坑了!!!
  • 文件位置为跟目录的同级目录!!!

方法二

麻烦点,使用JVM工具:HSDB,此工具既可以查看jdk生成的动态代理对象,也可以查看cglib生成的动态代理对象!
1. 获取PID

  • 断点,运行项目获取
    在获取动态代理类处设置断点,使用jps获取PID,我的PID为:16872
    PS C:\dev_workspace\other\stu> jps
    18944 Launcher
    21392 RemoteMavenServer36
    27664 Launcher
    19508 Jps
    24116 
    17508 JUnitStarter
    18216 
    PS C:\dev_workspace\other\stu> 
    

2. 执行命令,获取HSDB(HostSpot Debugger)工具:

java -classpath "%JAVA_HOME%/lib/sa-jdi.jar" sun.jvm.hotspot.HSDB

3. 将PID填入HSDB工具
填坑之动态代理生成的代理类文件在哪?_第5张图片
填坑之动态代理生成的代理类文件在哪?_第6张图片
填入后:
填坑之动态代理生成的代理类文件在哪?_第7张图片
4.获取代理对象

  • 查看代理对象地址,可以看到此处为Proxy24@3339
    填坑之动态代理生成的代理类文件在哪?_第8张图片
  • 使用HSDB搜索此对象
    填坑之动态代理生成的代理类文件在哪?_第9张图片
    填坑之动态代理生成的代理类文件在哪?_第10张图片
    5. 生成代理对象
    填坑之动态代理生成的代理类文件在哪?_第11张图片
    填坑之动态代理生成的代理类文件在哪?_第12张图片

点击此链接后将会生成代理对象,位置在C盘中,个人用户下的com文件夹下, 如:
填坑之动态代理生成的代理类文件在哪?_第13张图片
6.查看生成的代理对象
继续暴力拖拽至IDEA中
图略。。。

方法三

感觉是最麻烦的一种:IO流,通过代码使用IO的方式,将代理对象以流的方式写入文件中,感觉太麻烦了,偷个懒,略了略了。。。

你可能感兴趣的:(那些年填过的坑,java,代理模式)