关键代码:

1.Proxy.newInstance:

private static final Class<?>[] constructorParams = { InvocationHandler.class };
Class<?> cl = getProxyClass0(loader, intfs);
final Constructor<?> cons = cl.getConstructor(constructorParams);
return cons.newInstance(new Object[]{h});

2.Proxy.getProxyClass0:

// otherwise, it will create the proxy class via the ProxyClassFactory
return proxyClassCache.get(loader, interfaces);

3.WeakCache.get(由2注释可知,首次是由ProxyClassFactory生成的class对象,proxyClassCache即WeakCache):

Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));

可见,这里调用ProxyClassFactory的apply方法;

4.ProxyClassFactory.apply:

long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
return defineClass0(loader, proxyName,proxyClassFile, 0, proxyClassFile.length);

这里先取一个原子整数作为序号,生成代理对象名称,com.sun.proxy.$Proxy0.class,

然后通过ProxyGenerator.generateProxyClass获得class的字节码,然后调用native方法defineClass0创建class对象。

由上可知,先在ProxyClassFactory的apply方法中通过ProxyGenerator.generateProxyClass得到字节码,调用defineClass0由字节码得到class对象(是个native方法),然后在Proxy.newInstance里得到这个class对象的构造器,然后反射得到代理对象实例。

通过ProxyGenerator.generateProxyClass(Openjdk能看到该类的源码)可以生成代理对象的字节码byte[] data,然后将其写到磁盘文件(.class后缀),即可看到代理对象的class文件了:

FileOutputStream fos = new FileOutPutStream("$Proxy0.class");
fos.write(data);
fos.close();

使用jd反编译:

该class继承了Proxy,实现了被代理对象的接口。构造方法传入InvocationHandler,调用super(invocationHandler);实现的被代理接口的方法里面其实是调用的invocationHandler.invoke方法(Object proxy参数传入的代理对象this)。

使用动态代理:

1)实现InvocationHandler接口(增强),并持有被代理对象实例,并在它的invoke方法里面写增强逻辑,该方法的参数是代理对象,方法和参数,在invoke合适的位置调用被代理对象的方法(使用反射的方式method.invoke(target, args));
2)使用Proxy.newInstance创建代理对象,classloader(加载生成的动态代理类字节码为class对象)使用被代理对象的classloader即可(target.getClass.getClassLoader),interfaces使用被代理对象的接口数组(target.getClass.getInterfaces)。 return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);

JDK动态代理源码剖析的更多相关文章

  1. 深入剖析JDK动态代理源码实现

    动态代理.静态代理优缺点优点:业务类只需要关注业务逻辑本身,保证了业务类的重用性.这是代理的共有优点.动态代理只有在用到被代理对象的时候才会对被代理类进行类加载. 而静态代理在编译器就已经开始占内存了 ...

  2. JDK动态代理源码学习

    继上一篇博客设计模式之代理模式学习之后http://blog.csdn.net/u014427391/article/details/75115928,本博客介绍JDK动态代理的实现原理,学习一下JD ...

  3. jdk 动态代理源码分析

    闲来无事,撸撸源码 使用方法 直接看代码吧.. package com.test.demo.proxy; import java.lang.reflect.InvocationHandler; imp ...

  4. JDK动态代理源码解析

    动态代理.静态代理优缺点     关于JDK的动态代理,最为人熟知的可能要数Spring AOP的实现,默认情况下,Spring AOP的实现对于接口来说就是使用的JDK的动态代理来实现的,而对于类的 ...

  5. JDK动态代理源码分析

    先抛出一个问题,JDK的动态代理为什么不支持对实现类的代理,只支持接口的代理??? 首先来看一下如何使用JDK动态代理.JDK提供了Java.lang.reflect.Proxy类来实现动态代理的,可 ...

  6. 设计模式之JDK动态代理源码分析

    这里查看JDK1.8.0_65的源码,通过debug学习JDK动态代理的实现原理 大概流程 1.为接口创建代理类的字节码文件 2.使用ClassLoader将字节码文件加载到JVM 3.创建代理类实例 ...

  7. 动态代理学习(二)JDK动态代理源码分析

    上篇文章我们学习了如何自己实现一个动态代理,这篇文章我们从源码角度来分析下JDK的动态代理 先看一个Demo: public class MyInvocationHandler implements ...

  8. java 1.8 动态代理源码分析

    JDK8动态代理源码分析 动态代理的基本使用就不详细介绍了: 例子: class proxyed implements pro{ @Override public void text() { Syst ...

  9. java动态代理源码解析

    众所周知,java动态代理同反射原理一直是许多框架的底层实现,之前一直没有时间来分析动态代理的底层源码,现结合源码分析一下动态代理的底层实现 类和接口 java动态代理的主要类和接口有:java.la ...

随机推荐

  1. ustc FreeBSD / rust 镜像源

    http://mirrors.ustc.edu.cn/help/ Rust Crates 源使用帮助 地址 https://mirrors.ustc.edu.cn/crates.io-index/ 说 ...

  2. UVA1608_Non-boring sequences

    Non-boring sequences 大致题意: 给你一个字符串,问你他的任一子串是否都包含一个唯一的字符 思路: 看似简单,实际一丁点思路都没有 后面看汝佳的讲解都看了好长时间 大概思路就是,先 ...

  3. 【题解】图的m着色问题

    题目背景 给定无向连通图G和m种不同的颜色.用这些颜色为图G的各顶点着色,每个顶点着一种颜色.如果有一种着色法使G中每条边的2个顶点着不同颜色,则称这个图是m可着色的.图的m着色问题是对于给定图G和m ...

  4. K8S入门系列之必备扩展组件--> coredns(四)

    摘要: 集群其他组件全部完成后我们应当部署集群 DNS 使 service 等能够正常解析,1.11版本coredns已经取代kube-dns成为集群默认dns. https://github.com ...

  5. IT面试技巧(2)

    21.最能概括你自己的三个词是什么? 回答提示:我经常用的三个词是:适应能力强,有责任心和做事有始终,结合具体例子向主考官解释, 22.你的业余爱好是什么? 回答提示:找一些富于团体合作精神的,这里有 ...

  6. 【问题解决方案】单个文件夹嵌套时github仓库中最外层文件夹直接显示所有嵌套文件夹名的问题

    上传文件的时候遇到这样一个问题: 这么看着好像有什么问题,直觉不应该这么显示吧 折腾半天,从github新建了嵌套文件夹并同步到本地,然后从本地push了文件,结果依然显示是这样 好吧,那这个问题应该 ...

  7. 2019-9-2-win10-uwp-九幽图床

    title author date CreateTime categories win10 uwp 九幽图床 lindexi 2019-09-02 12:57:38 +0800 2018-2-13 1 ...

  8. json书写格式

    1.数组方式 [ ] [{ "id" : 1 , "name" : "xiaoming" },{ "id" : 2 , ...

  9. 【leetcode】640. Solve the Equation

    题目如下: 解题思路:本题的思路就是解析字符串,然后是小学时候学的解方程的思想,以"2x+3x-6x+1=x+2",先把左右两边的x项和非x项进行合并,得到"-x+1=x ...

  10. MySQL(关系型数据库管理系统)

    MySQL 关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的 RDBMS ...