我试图找到可用的答案,但是没有运气。我想知道是否可以使用字节伙伴来执行以下操作: 假设我们有一个带有多个值的POJO。对于某些特定类型的处理,我仅对某些感兴趣。我可以用注解标记它们,例如@ConditionalData可以放在吸气剂或字段上。 然后,我可以创建接口,让我们说NVPProvider,它将返回地图字段名称-值。 可以通过反射执行此操作,但效果不太好。我希望我可以使用字节伙伴来通过接口和Implement方法扩展类,但是我并没有真正找到如何构造Implementation来实现该目标的方法。
我已经完成了以下实现:
net.bytebuddy.implementation.Implementation
并尝试在网页上搜索一些示例,但我还没有意识到正确的选择方法。
public interface NVPProvider {
Map<String, Object> getDataAsNVP();
}
public <O> Builder<O> instrumentType(Builder<O> builder) {
builder.implement(NVPProvider.class).method(net.bytebuddy.matcher.ElementMatchers.named("getDataAsNVP")).intercept( ??? );
return builder.implement(NVPProvider.class);
}
我想知道是否存在一种方法,可以通过反射性地获取批注来迭代字段和获取器并匹配Accessible对象,但是基于此,我将能够构成接口方法实现,以迭代匹配的字段并为结果图,假想的生成代码如下:
Map<String, Object> result = new HashMap<>();
Object obj0 = getValue001();
result.put("getValue001", obj0);
Object ob10 = accesibleField1;
result.put("ob10 ", ob10 );
稍后我可以添加注解属性,以使键看起来更好。
我看过
的示例MethodDelegation.to(interceptor)
但是,现在我要看看如何做到无反射。
我知道如何使用Javassist做到这一点,您实际上可以在其中编写稍后再编译的代码,但是我不确定如何用字节伙伴来做到这一点。我已经使用字节预算通过配置文件中动态定义的简单getter扩展了POJO,它看起来不错。仅使用一个字节操作工具会更清洁。 感谢您的任何建议。
答案 0 :(得分:0)
这在Byte Buddy中是可能的,但是您必须通过实现自己的Implementation
或其底层ByteCodeAppender
来制造自定义方法主体。您可以直接使用ASM,因为这样的访问者可以暴露他们的MethodVisitor
,但要容易一些,您还可以使用 net.bytebuddy.implementation.bytecode 包中提供的更高级别的构造。对于您所描述的方法,您首先要实例化哈希图:
List<StackManipulation> m = new ArrayList<>();
// new HashMap<>();
m.add(TypeCreation.of(HashMap.class));
m.add(Duplication.SINGLE);
m.add(MethodInvocation.invoke(new MethodDescription.ForLoadedConstructor(HashMap.class.getConstructor());
随后,ByteCodeAppender
提供了对检测类型的描述,您可以从中导航到所有字段和方法,例如:
FieldDescription field = ...
// map.put(fieldName, fieldValue);
m.add(Duplication.SINGLE);
m.add(new TextConstant(field.getName());
m.add(MethodVariableAccess.loadThis());
m.add(FieldAccess.forField(field).read());
m.add(MethodInvocation.invoke(Map.class.getMethod("put", Object.class, Object.class)));
m.add(Removal.SINGLE);
上面的代码首先在堆栈上复制哈希映射以保留它以供进一步访问,然后将字段名称添加到堆栈上,加载字段值,然后调用Map::put
方法。最后,它删除put方法的返回值。
最后,您需要通过添加MethodReturn.REFERENCE
来返回地图。
您可以查看Byte Buddy中的其他Implementation
来详细了解它的工作原理,ASM为字节码基础知识提供了很好的教程,以解释字节码模式需要遵循的堆栈隐喻。