Byte Buddy中如何使用Advice.WithCustomMapping绑定动态新增字段
引用动态新增字段的解决方法
你代码中无法通过td.getDeclaredFields()获取到本次transform中刚新增的字段,是因为td代表的是类被修改前的原始结构描述,不包含当前正在添加的字段内容。DynamicType.Builder#defineField方法执行完成后会直接返回你刚刚定义的字段对应的FieldDescription实例,你直接捕获这个实例用于绑定即可,修改后的代码示例:
AgentBuilder ab = new AgentBuilder.Default(); // ... ab = ab.type(named(type)) .transform((builder, td, _cl, _m) -> { // 捕获新增字段的FieldDescription FieldDescription.InDefinedShape latField = builder .defineField("$lat$", LatencyEvent.class, Visibility.PUBLIC) .build(); return builder .visit(Advice.withCustomMapping() // 直接传入捕获到的字段实例进行绑定 .bind(Lat.class, latField) .to(EndLatAdvice.class) .on(isMethod().and(named(until)))); });
如果你需要新增多个同类型字段,只需要依次捕获每个字段的FieldDescription,分别绑定到不同的自定义注解即可。
自定义绑定实现可写字段的配置
如果要让自定义绑定的字段支持写入,不需要直接传FieldDescription,而是传入配置好读写权限的Advice.FieldValue实例即可,示例如下:
.visit(Advice.withCustomMapping() // 配置字段为可写模式 .bind(Lat.class, Advice.FieldValue.of(latField).readOnly(false)) .to(EndLatAdvice.class) .on(isMethod().and(named(until))))
同时需要注意,Advice方法中接收该字段的参数不要加final修饰,如果你需要直接修改字段的值,还可以将参数声明为数组类型(数组的第一个元素对应字段值,修改数组元素即可同步到字段),具体写法和原生@Advice.FieldValue的可写用法完全一致:
private static class EndLatAdvice { @Advice.OnMethodEnter static void enter(@Lat LatencyEvent[] l) { // 修改数组第0位即可回写到绑定字段 l[0] = new LatencyEvent(); } }
内容的提问来源于stack exchange,提问作者Sassa NF
相关产品推荐
相关产品推荐

