一个ProxyGenerator
实例代表一个代理类
ProxyGenerator
实例中重要的属性
/** 保存所有接口的方法, key为方法签名, value中位不同返回值的同签名方法 */
Map<String, List<ProxyMethod>> proxyMethods;
/** 保存最终的字段信息, 每一个元素会生成一个实例字段 */
List<FieldInfo> fields;
/** 保存最终的方法信息, 每一个元素会生成一个实例方法 */
List<MethodInfo> methods;
#generateClassFile()
生成入口, 返回代理类字节码
步骤- 通过
#addProxyMethod(Method, Class)
注册hashCode
,equals
,toString
方法 - 通过
#addProxyMethod(Method, Class)
循环注册每个接口的每个方法 - 对所有注册方法的返回值进行最终校验
- 通过
#generateConstructor()
将构造方法添加到最终信息区 - 遍历
#proxyMethods
, 将每一个ProxyMethod
转变为一个FieldInfo
及一个MethodInfo
- 通过
#generateStaticInitializer()
将静态代码块添加到最终信息区
- 通过
#generateStaticInitializer()
代理类的静态代码块
static{}
, 该代码块会注册每个方法的原生引用#generateConstructor()
代理类的构造方法, 此处会调用父类的构造, 该构造及父构造都拥有一个参数
InvocationHandler
$ProxyMethod#codeFieldInitialization(DataOutputStream out)
调用方:
#generateStaticInitializer()
用于生成获取原生方法引用的字节码(Class.forName(...).getMethod(...)
)$ProxyMethod#generateMethod()
调用方:
#generateClassFile()
用于生成代理类的方法主体#addProxyMethod(Method, Class)
向实例属性
#proxyMethods
注册方法签名.
如果方法签名已添加(不同类的同签名方法), 则判断返回值.
如果返回值完全相同, 将其合并, 异常集将取两方法异常集的交集.
如果返回值不相同, 添加到同一个Entry中, 等待后续校验.