Каков самый простой способ создать эффективную реализацию интерфейса Java во время выполнения?

Начиная с одного базового интерфейса Java, я хочу, чтобы другие могли расширять этот интерфейс прямо или косвенно и добавлять к нему свойства и поведение bean-компонентов в качестве системы надстроек.

Затем, во время выполнения на пользовательском компьютере, я нашел все эти интерфейсы и сгенерировал один большой класс, реализующий их все. Поля, необходимые для свойств компонента, будут сгенерированы автоматически, в то время как поведение, определенное в интерфейсах, будет реализовано как статические методы вспомогательного класса (созданного разработчиками подключаемого модуля), которые принимают соответствующий интерфейс в качестве первого параметра, поэтому реализация интерфейсный метод делегировал бы статическому методу, передав "this" в качестве первого параметра.

Это похоже на то, как Scala реализует свои свойства.

Я вижу 3 способа сделать это:

  1. Используйте динамические прокси Java, основанные на отражении.
  2. Сгенерируйте исходный код в виде строки и скомпилируйте ее во время выполнения.
  3. Используйте некоторую библиотеку манипуляций с байт-кодом для создания класса во время выполнения.

Вариант 1 - самый простой, но наименее эффективный, поэтому мне нужно лучшее решение. Вариант 2 дал бы мне эффективную реализацию, но он довольно уродлив.

Хотя я видел несколько библиотек, которые могут использовать вариант 3, все они, похоже, требуют, чтобы я сначала выучил язык ассемблера Java, что я считаю занятием, требующим очень много времени с небольшими преимуществами в конечном итоге.

Поскольку я не хочу изучать какой-либо ассемблер, JVM или что-то еще, вариант 2 мой лучший вариант, или есть библиотеки, которые могут генерировать динамические прокси без меня, используя ассемблер JVM?


person Sebastien Diot    schedule 14.07.2011    source источник


Ответы (2)


Взгляните на Javassist. С его помощью вы можете вносить изменения во время выполнения в классы, используя простой API. Вам не нужно знать о «черной магии» Java, чтобы использовать ее.

person Bohemian♦    schedule 14.07.2011
comment
Я нашел этот пример здесь today.java.net/pub/a/today/2008/04/24/, что мне было легче понять, чем пример BCEL. - person Sebastien Diot; 15.07.2011
comment
Вот с домашней страницы Javaassist: Javassist обеспечивает абстракцию на уровне исходного кода; программисты могут изменять файл класса без подробных знаний байт-кода Java. Им не нужно даже записывать вставленную последовательность байт-кода. - person Sebastien Diot; 15.07.2011

При использовании BCEL вам не обязательно знать java-ассемблер. Лок на этом прокси-сервере.

person zacheusz    schedule 14.07.2011
comment
В этом примере вам все еще нужно добавить такие вещи, как il.append (new ALOAD (0)), который является ассемблером JVM. Мне было легче следовать примеру Javaassist. - person Sebastien Diot; 15.07.2011