Можно ли вернуться из метода, используя @ Advice.OnMethodEnter? - PullRequest
0 голосов
/ 08 мая 2018

Используя API рекомендаций Byte Buddy, можно ли вернуться из инструментального метода, не выполнив его на самом деле?

Одним из вариантов использования будет реализация кэша и возврат кэшированного значения, если оно есть, вместо повторного вычисления значения.

@Advice.OnMethodEnter
public static Object returnCachedValue(@Advice.Argument(0) String query) {
    if (cache.containsKey(query)) {
        // should "abort" method call
        return cache.get(query);
    }
}

Я знаю, что этот пример кода выше просто создает локальную переменную, которую я могу получить в методе @Advice.OnMethodExit. Но есть ли способ прервать вызов метода в явном return? Если да, возможно ли это для void методов?

1 Ответ

0 голосов
/ 10 мая 2018

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

class MyAdvice {
  @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
  public static Object returnCachedValue(@Advice.Argument(0) String query) {
    if (cache.containsKey(query)) {
      return cache.get(query);
    } else {
      return null;
    }
  }

  @Advice.OnMethodExit
  public static Object processCachedValue(
          @Advice.Return(readOnly = false, typing = DYNAMIC) Object returned,
          @Advice.Enter Object enter) {
    if (enter != null) {
      returned = enter;
    } else {
      cache.put(query, returned);
    }
  }
}

Конечно, это не работает, если кэшированное значение равно null. Чтобы избежать этого, вы можете в некоторых случаях обернуть значение, чтобы убедиться, что введенное значение никогда не будет null. Это также позволит использовать вышеуказанный шаблон для void методов.

Это может показаться неудобным для программы, но идея рекомендации заключается в том, что Byte Buddy может использовать класс рекомендации в качестве шаблона и встроить байт-код без особых усилий, чтобы избежать накладных расходов во время выполнения.

...