Как вы используете Java 1.6 Annotation Processing для выполнения ткачества во время компиляции? - PullRequest
7 голосов
/ 28 апреля 2010

Я создал аннотацию, применил ее к DTO и написал обработчик аннотаций в стиле Java 1.6. Я вижу, как сделать так, чтобы annotationProcessor записывал новый исходный файл, а это не то, что я хочу, я не могу увидеть или узнать, как заставить его изменить существующий класс (в идеале просто изменить байтовый код). Модификация на самом деле довольно тривиальна, все, что я хочу, чтобы процессор сделал, это вставил новый метод получения и установки, где имя происходит от значения обрабатываемой аннотации.

Мой процессор аннотаций выглядит так:

@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes({ "com.kn.salog.annotation.AggregateField" })
public class SalogDTOAnnotationProcessor extends AbstractProcessor {

    @Override
    public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
        //do some stuff
    }
}

Ответы [ 4 ]

6 голосов
/ 29 апреля 2010

По своей конструкции средство обработки аннотаций не допускает непосредственного изменения обрабатываемого исходного кода.Однако можно генерировать подклассы обрабатываемого типа или суперкласс обрабатываемого типа.При некотором планировании это позволяет частично повлиять на изменение рассматриваемого типа.Я написал пример того, как это может соответствовать друг другу;см. эту запись в блоге для более подробного объяснения и некоторого примера кода.

6 голосов
/ 04 мая 2010

Вы ищете "Инструментарий", который делают фреймворки, такие как AspectJ. В этом случае вам нужно указать jar в командной строке с опцией «-agent», а затем иметь возможность фильтровать все загруженные классы. На этом шаге фильтрации вы можете проверить наличие аннотаций и изменить байт-код до его загрузки в виртуальную машину. Библиотеки для выполнения реальной модификации байт-кода включают «asm» и, возможно, высокоуровневые оболочки «cglib» и «javassist». Вы даже можете предварительно скомпилировать ваши классы, чтобы сгенерировать список классов, которые вы должны инструктировать, чтобы немного ускорить фильтрацию в начале.

См. Java.lang.instrumentation для получения дополнительной информации.

5 голосов
/ 05 апреля 2012

Вы должны использовать классы внутреннего компилятора - немного вдохновения:

Но это балансирование на грани. Ваша программа будет компилироваться только на Sun / OpenJDK, и в будущих версиях могут возникнуть проблемы (внутренний API может измениться). Хотя после компиляции он является стандартным байт-кодом и будет работать везде.

Кстати: если вы хотите использовать его в Eclipse, вы должны добавить некоторую специальную поддержку для него, потому что Eclipse использует нестандартный компилятор. Ваш дизайн должен быть более сложным, и вы должны добавить уровень абстракции к вашему процессору, как это делает Lombok .

0 голосов
/ 28 апреля 2010

Для этого вы должны расширить компилятор javac, что означает, что сборка вашей программы не будет такой переносимой, как обычное приложение. См. http://weblogs.java.net/blog/cayhorstmann/archive/2006/06/say_no_to_prope.html для получения дополнительной информации о том, как кто-то достиг этого.

...