Java 使用Byte buddy而不是MethodDelegation定义方法体

Java 使用Byte buddy而不是MethodDelegation定义方法体,java,byte-buddy,Java,Byte Buddy,我正试图根据运行时可用的一些配置,使用Byte Buddy生成一个类和其中的方法。该类正在尝试创建Hazelcast喷射管道以连接多个IMAP 根据提供的配置,要加入的IMAP数量可能会有所不同。在下面的示例中,我尝试加入三个IMAP private Pipeline getPipeline(IMap<String, Object1> object1Map, IMap<String, Object2> object2Map, IMap<String

我正试图根据运行时可用的一些配置,使用Byte Buddy生成一个类和其中的方法。该类正在尝试创建Hazelcast喷射管道以连接多个IMAP

根据提供的配置,要加入的IMAP数量可能会有所不同。在下面的示例中,我尝试加入三个IMAP

private Pipeline getPipeline(IMap<String, Object1> object1Map, IMap<String, Object2> object2Map, 
        IMap<String, Object3> object3Map) {
    Pipeline p = Pipeline.create();

    BatchStage<Entry<String, Object1>> obj1 = p.drawFrom(Sources.map(object1Map));
    BatchStage<Entry<String, Object2>> obj2 = p.drawFrom(Sources.map(object2Map));
    BatchStage<Entry<String, Object3>> obj3 = p.drawFrom(Sources.map(object3Map));

    DistributedFunction<Tuple2<Object1, Object2>, String> obj1Obj2JoinFunc = entry -> entry.f1().getField31();
    DistributedBiFunction<Tuple2<Object1, Object2>, Object3, Tuple2<Tuple2<Object1, Object2>, Object3>> output = (
        in1, in2) -> (Tuple2.tuple2(in1, in2));

    BatchStage<Tuple2<Object1, Object2>> obj1_obj2 = obj1.map(entry -> entry.getValue())
            .hashJoin(obj2.map(entry -> entry.getValue()),
                    JoinClause.onKeys(Object1::getField11, Object2::getField21), Tuple2::tuple2).filter(entry -> entry.getValue() != null);

    BatchStage<Tuple2<Tuple2<Object1, Object2>, Object3>> obj1_obj2_obj3 = obj1_obj2.hashJoin(
            obj3.map(entry -> entry.getValue()),
            JoinClause.onKeys(obj1Obj2JoinFunc, Object3::getField31), output)
            .filter(entry -> entry.getValue() != null);

    // the transformResult method will get the required fields from above operation and create object of AllObjectJoinClass
    BatchStage<Entry<String, AllObjectJoinClass>> result = transformResult(obj1_obj2_obj3);
    result.drainTo(Sinks.map("obj1_obj2_obj3"));
    return p;
私有管道getPipeline(IMap object1Map、IMap object2Map、, IMap对象(3MAP){ Pipeline p=Pipeline.create(); BatchStage obj1=p.drawFrom(Sources.map(object1Map)); BatchStage obj2=p.drawFrom(Sources.map(object2Map)); BatchStage obj3=p.drawFrom(Sources.map(object3Map)); DistributedFunction obj1Obj2JoinFunc=entry->entry.f1().getField31(); 分布式双功能输出=( in1,in2)->(Tuple2.Tuple2(in1,in2)); BatchStage obj1_obj2=obj1.map(条目->条目.getValue()) .hashJoin(obj2.map(entry->entry.getValue()), onKeys(Object1::getField11,Object2::getField21),Tuple2::Tuple2).filter(entry->entry.getValue()!=null); BatchStage obj1_obj2_obj3=obj1_obj2.hashJoin( obj3.map(entry->entry.getValue()), onKeys(obj1Obj2JoinFunc,Object3::getField31),输出) .filter(entry->entry.getValue()!=null); //transformResult方法将从上述操作中获取所需字段,并创建AllObjectJoinClass的对象 BatchStage结果=转换结果(obj1_obj2_obj3); result.drainTo(Sinks.map(“obj1_obj2_obj3”); 返回p; }

这里的问题是,我的方法的参数数量取决于运行时配置,这也决定了方法体。 我能够使用
TypeDescription.Generic.Builder.parameterizedType
生成方法签名。 但是,我在生成方法体时遇到问题。我尝试使用
MethodDelegation.to
,以便该方法驻留在单独的类中。这种方法的问题在于,独立类中的方法需要非常通用,以便它可以接受任意数量的不同类型的参数,并且还需要了解IMap中每个对象的字段

我想知道是否有另一种方法可以通过某种类型的模板来实现这一点,这样就可以为具有此主体的每个管道生成单独的类。我没有找到任何用于生成具有定义体的方法的文档(可能我遗漏了什么)


--Anoop

这在很大程度上取决于你想做什么:

  • 使用
    Advice
    ,您可以将模板作为内联到方法中的字节码编写
  • 使用
    StackManipulation
    s,您可以编写单个字节码指令
  • 在我看来,选择(2)是你的目标。对于单独编写的代码,这通常是最简单的选择

    编写单个字节码当然不是最方便的选择,但是如果您可以轻松地编写每个输入的处理,那么您可能可以编写多个
    Advice
    类,以避免直接使用字节码指令