Добавить / генерировать методы во время компиляции

В настоящее время я создаю API, который я буду просить у многих разработчиков. Большая часть этого проста, но есть пара вызовов API, которые являются сложными по своей природе, но должны использоваться в значительной степени стандартным способом.

Я хотел бы создать шаблонный код внутри классов, возможно, пометив некоторые аннотации, но эти сгенерированные методы должны быть доступны в Eclipse / IntelliJ, чтобы их мог увидеть разработчик. Я посмотрел на Javassist, но не уверен, что природа выполнения - это хорошо. Я предпочел бы подход времени компиляции.

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

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

2 ответа

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

Если вы готовы признать, что используется какая-то инфраструктура, вы можете сделать это без генерации кода / байт-кода:

  • Для каждой важной концепции напишите интерфейс, который полностью определяет API.
  • Теперь напишите соответствующий класс, который не реализует интерфейс, но соответствует сигнатурам методов не стандартных API. Вы можете использовать соглашение об именах для их объединения.
  • Напишите фабрику, которая генерирует реализации интерфейса с использованием Java Proxies. Прокси будет делегировать реализации всякий раз, когда это возможно. Стандартный код будет реализован непосредственно в обработчике реализации.
  • Вам могут понадобиться различные типы обработчиков вызовов, в этом случае рассмотрите соглашение об именах для них.
  • Если вам не нравится непроверенная связь между логикой и интерфейсом, извлеките суперинтерфейс, который не содержит шаблонных API.
  • Логика, которая использует эти конструкции, будет запрашивать экземпляры по имени интерфейса; Фабрика будет знать, как создать экземпляр базовой логики и обработчик вызовов.

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

Сама манипуляция может быть выполнена с помощью пользовательского загрузчика классов или во время начальной загрузки классов с помощью агентов Java. Но как сделать API доступным для разработчиков? Вот несколько идей:

  • Сделайте классы реализации абстрактными и объявите абстрактные методы, в которых будет сгенерирован шаблонный код.

  • Напишите заглушки реализации шаблонных методов (т.е. ничего не делать в void методы; бросать RuntimeException во всех остальных.) Отметьте эти методы с некоторой аннотацией.

  • Сделайте что-то вроде того, что делает Google Web Toolk it, и объявите стандартные методы как native, Это похоже на маркировку методов abstract, но позволяет делать такие вещи, как создание классов final,

Компилятор Java имеет поддержку обработки аннотаций. Вы можете написать свои собственные процессоры, которые будут генерировать код в соответствии с вашими аннотациями.

Другие вопросы по тегам