Определите тело метода с помощью Byte buddy вместо MethodDelegation - PullRequest
3 голосов
/ 26 марта 2019

Я пытаюсь сгенерировать в нем класс и методы, используя Byte Buddy, основываясь на некоторой конфигурации, доступной во время выполнения.Класс пытается создать конвейер Hazelcast Jet для объединения нескольких IMaps.

В зависимости от предоставленной конфигурации, нет.IMaps, чтобы присоединиться может варьироваться.В приведенном ниже примере я пытаюсь присоединиться к трем IMaps.

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;

}

Проблема в том, что нет.Аргументы моего метода зависят от конфигурации среды выполнения, и это также определяет тело метода.Я могу сгенерировать подпись метода, используя TypeDescription.Generic.Builder.parameterizedType.Но у меня возникли проблемы при создании тела метода.Я попытался использовать MethodDelegation.to, чтобы метод находился в отдельном классе.Проблема с этим подходом состоит в том, что метод в отдельном классе должен быть очень универсальным, чтобы он мог принимать произвольное нет.аргументов разных типов, а также необходимо знать о полях каждого из объектов в IMap.

Интересно, есть ли альтернативный подход к достижению этого с помощью, возможно, шаблонов некоторого типа, чтобы отдельный классможет быть создан для каждого конвейера с этим телом.Я не нашел никакой документации для генерации метода с определенным телом (возможно, я что-то пропустил).

- Anoop

1 Ответ

0 голосов
/ 27 марта 2019

Это очень сильно зависит от того, что вы пытаетесь сделать:

  1. С помощью Advice вы можете написать шаблон в виде байтового кода, который встроен в ваш метод.
  2. С помощью StackManipulation s вы можете составлять отдельные инструкции байт-кода.

Мне кажется, что вариант (2) - это то, к чему вы стремитесь. Для индивидуально составленного кода это часто самый простой вариант.

Написание индивидуального байтового кода, конечно, не самый удобный вариант, но если вы можете легко составить обработку каждого ввода, вы можете составить несколько классов Advice, чтобы избежать непосредственного использования инструкций байтового кода.

...