Инструмент apt и его связанный API, содержавшийся в пакете, com.sun.mirror был осужден начиная с JDK 7 и планируется, чтобы быть удаленным в следующем главном выпуске JDK. Используйте опции, доступные в инструменте javac и API, содержавшихся в пакетах javax.annotation.processing и javax.lang.model обработать аннотации.
Утилита командной строки apt, инструмент обработки аннотации, находит и выполняет процессоры аннотации, основанные на аннотациях, существующих в наборе указанных исследуемых исходных файлов. Процессоры аннотации используют ряд отражающих API и инфраструктуры поддержки, чтобы выполнить их обработку аннотаций программы (JSR 175). apt отражающие API обеспечивает разовое сборкой, основанное на источнике, представление только для чтения структуры программы. Эти отражающие API разрабатываются, чтобы чисто смоделировать систему типов языка программирования JavaTM после добавления обобщений (JSR 14). Во-первых, apt процессоры аннотации выполнений, которые могут произвести новый исходный код и другие файлы. Затем, apt может вызвать компиляцию и исходных и сгенерированных исходных файлов, таким образом ослабляя цикл разработки.
Многие из намеченных вариантов использования для аннотаций включают аннотации наличия в основной файл, содержат информацию, которая используется, чтобы генерировать новые полученные файлы (исходные файлы, файлы класса, дескрипторы развертывания, и т.д.), которые являются логически непротиворечивыми с основным файлом и его аннотациями. Другими словами, вместо того, чтобы вручную поддержать непротиворечивость среди всего набора файлов, только основной файл должен был бы сохраняться, так как полученные файлы сгенерированы. Инструмент apt разрабатывается для того, чтобы создать полученные файлы.
По сравнению с использованием doclet, чтобы генерировать полученные файлы, основанные на аннотациях, apt
имеет более чистую модель объявлений и текущую структуру типа программ
использует более современный проект API, такой как возврат универсальных наборов вместо массивов и обеспечения посетителей, чтобы работать на объявлениях и типах
поддерживает рекурсивную обработку недавно сгенерированных файлов и может автоматически вызвать компиляцию исходных и сгенерированных исходных файлов
В то время как предназначено для обработки аннотации, apt может использоваться для других отражающих задач программирования также.
Во-первых, apt определяет то, на чем аннотации присутствуют на исходном коде, управляемом. Затем, apt ищет фабрики процессора аннотации, которые Вы записали. Инструмент спрашивает фабрики, какие аннотации они обрабатывают. Затем apt просит, чтобы фабрика обеспечила процессор аннотации, если фабрика обрабатывает аннотацию, существующую в исходных файлах, управляемых на. Затем, процессоры аннотации выполняются. Если процессоры генерировали новые исходные файлы, apt повторит этот процесс, пока никакие новые исходные файлы не будут сгенерированы.
com.sun.mirror.util: различные утилиты для того, чтобы обработать типы и объявления, включая посетителей
Каждый процессор реализует интерфейс AnnotationProcessor в пакете com.sun.mirror.apt. У этого интерфейса есть один метод - process - используемый инструментом apt, чтобы вызвать процессор. Процессор "обработает" один или более типов аннотации.
Экземпляр процессора возвращается его соответствующей фабрикой - AnnotationProcessorFactory. Инструмент apt вызывает метод getProcessorFor фабрики, чтобы овладеть процессором. Во время этого вызова инструмент обеспечивает AnnotationProcessorEnvironment. В среде процессор найдет все, что это должно начать, включая ссылки на структуру программы, на которой это работает, и средства связаться и сотрудничать с инструментом apt, создавая новые файлы и передавая предупреждающие сообщения и сообщения об ошибках.
Есть два способа, которыми может быть найдена фабрика; фабрика, чтобы использовать может быть определена через параметр командной строки "-factory", или фабрика может быть расположена во время
процедуры открытияapt. Используя "-factory" опция является самым простым способом выполнить единственную известную фабрику; эта опция может также использоваться, когда фабрика нуждается в большем количестве управления тем, как это выполняется. Чтобы определить местоположение фабрик на определенном пути, процедура открытия получает от файлов фляги информацию о META-INF/services в формате, описанном ниже.
Создать и использовать процессор аннотации, используя опцию "-factory":
Запишите AnnotationProcessorFactory, который поочередно может создать AnnotationProcessor для типа (ов) аннотации интереса.
Скомпилируйте процессоры и фабрики, используя javac с tools.jar на пути к классу; tools.jar содержит интерфейсы com.sun.mirror.*.
Поместите скомпилированные файлы класса, или файлы фляги, содержащие файлы класса, на соответствующем пути, вызывая apt
Чтобы создать и использовать процессор аннотации с процедурой открытия по умолчанию используют те же самые первые два шага тогда,
Создайте UTF-8 закодированный текстовый файл в META-INF/services по имени com.sun.mirror.apt.AnnotationProcessorFactory, содержание которого является списком полностью определенных имен конкретных классов фабрики, один на строку. (Это - тот же самый формат, используемый sun.misc.Service.)
Упакуйте фабрику, процессор, и информацию о META-INF/services в файл фляги
Поместите файл фляги в соответствующий путь, вызывая apt. Соответствующий путь обсуждается в разделе Открытия.
Процессор Аннотации Простой выборки
import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*;
import com.sun.mirror.type.*;
import com.sun.mirror.util.*;
import java.util.Collection;
import java.util.Set;
import java.util.Arrays;
import static java.util.Collections.*;
import static com.sun.mirror.util.DeclarationVisitors.*;
/*
* This class is used to run an annotation processor that lists class
* names. The functionality of the processor is analogous to the
* ListClass doclet in the Doclet Overview.
*/
public class ListClassApf implements AnnotationProcessorFactory {
// Process any set of annotations
private static final Collection<String> supportedAnnotations
= unmodifiableCollection(Arrays.asList("*"));
// No supported options
private static final Collection<String> supportedOptions = emptySet();
public Collection<String> supportedAnnotationTypes() {
return supportedAnnotations;
}
public Collection<String> supportedOptions() {
return supportedOptions;
}
public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env) {
return new ListClassAp(env);
}
private static class ListClassAp implements AnnotationProcessor {
private final AnnotationProcessorEnvironment env;
ListClassAp(AnnotationProcessorEnvironment env) {
this.env = env;
}
public void process() {
for (TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations())
typeDecl.accept(getDeclarationScanner(new ListClassVisitor(),
NO_OP));
}
private static class ListClassVisitor extends SimpleDeclarationVisitor {
public void visitClassDeclaration(ClassDeclaration d) {
System.out.println(d.getQualifiedName());
}
}
}
}
Много новых языков и функций библиотеки используются в демонстрационном процессоре. Во-первых, импорт static используется так, чтобы простое имя различных служебных методов могло использоваться; например "unmodifiableCollection" вместо "Collections.unmodifiableCollection". Во-вторых, универсальные наборы используются повсюду. Метод Arrays.asList является теперь методом var-args, таким образом, он может принять список разделенных запятой значений строк и создать список с требуемыми элементами. Метод Collections.emptySet является универсальным методом и может использоваться, чтобы создать безопасное с точки зрения типов пустое множество. Цикл for в методе процесса является улучшенным циклом for, который может выполнить итерации по наборам.
Определение Аннотаций, чтобы Обработать
Чтобы сказать инструмент, какие аннотации это обрабатывает, фабрика возвращает набор import - строки стиля, как показано в примере. У определенной строковой записи может быть одна из следующих трех форм:
*
Обработайте все аннотации. Это также обрабатывает пустой список аннотаций; другими словами фабрику, которая обрабатывает *, можно было попросить обеспечить нетривиальный процессор, даже если никакие аннотации не присутствуют. Эта возможность позволяет API com.sun.mirror использоваться, чтобы записать общие инструменты обработки исходного кода.
foo.bar.Baz
Обработайте аннотацию, каноническим именем которой является "foo.bar.Baz".
foo.bar.*
Аннотации процесса, канонические имена которых запускаются с "foo.bar.".
Инструмент apt дарит фабрике ряд аннотаций для фабрики, чтобы обработать. Основанный на наборе аннотаций и среды процессора аннотации, фабрика возвращает единственный процессор аннотации. Что, если фабрика хочет возвратить многократные процессоры аннотации? Фабрика может использовать com.sun.mirror.apt.AnnotationProcessors.getCompositeAnnotationProcessor, чтобы объединить и упорядочить работу многократных процессоров аннотации.
Определение Параметров командной строки, чтобы Распознать
Метод supportedOptions позволяет фабрике связываться с apt, какие параметры командной строки он распознает. Параметры командной строки, запускающиеся с "-A", резервируются для того, чтобы связаться с процессорами аннотации. Например, если эта фабрика распознает опции, такие как -Adebug и -Aloglevel=3, то это возвратит строки "-Adebug" и "-Aloglevel". В будущем apt может дать индикацию, если опциям -A дают, та никакая фабрика не распознает.
Способная Командная строка
В дополнение к его собственным опциям инструмент apt принимает все параметры командной строки, принятые javac. Опции javac передают к заключительному вызову javac, если любой.
apt определенные опции:
dir-s
Определите корень каталога, под которым будут помещены сгенерированные процессором исходные файлы; файлы помещаются в подкаталоги, основанные на пространстве имен пакета
-nocompile
Не компилируйте исходные файлы, чтобы классифицировать файлы.
-print
Распечатайте текстовое представление указанных типов; не выполните обработку аннотации или компиляцию.
-A [ключ [=val]]
Опции, чтобы передать к процессорам аннотации - они не интерпретируются apt непосредственно, но делаются доступными для использования отдельными процессорами
Путь-factorypath
Определите, где найти фабрики процессора аннотации; если эта опция используется, путь к классу не ищется фабрики.
Имя класса-factory
Имя AnnotationProcessorFactory, чтобы использовать; процесс открытия значения по умолчанию обходов
Как apt совместно использует некоторые из опций javac:
dir-d
Определите, куда поместить процессор и javac сгенерированные файлы класса
Путь-cp или
путь-classpath
Определите, где найти пользовательские файлы класса и фабрики процессора аннотации. Если -factorypath дается, путь к классу не ищется фабрики.
Есть некоторые apt скрытые опции, которые могут быть полезными для отладки:
-XListAnnotationTypes
Перечислите найденные типы аннотации
-XListDeclarations
Перечислите определенные и включенные объявления
-XPrintAptRounds
Информация о печати о начальных и рекурсивных раундах apt
-XPrintFactoryInfo
Информация о печати, о которой аннотациях фабрику просят обработать
После сканирования исходных файлов на командной строке, чтобы определить, какие аннотации присутствуют, по умолчанию инструмент apt ищет фабрики процессора аннотации на соответствующем пути. Если опция -factorypath используется, тот путь является соответствующим путем, чтобы искать фабрики; иначе, путь к классу является соответствующим путем. Фабрики запрашиваются, чтобы определить, какие аннотации они обрабатывают. Если фабрика обрабатывает одну из существующих аннотаций, ту аннотацию считают требуемой. Как только все аннотации требуются, инструмент не ищет дополнительные фабрики. После того, как аннотации все требуются, или больше фабрик не может быть найдено, apt вызовет методы getProcessorFor фабрик, передающие в наборе аннотаций, которых требовала фабрика. Каждая фабрика возвращает единственный процессор, чтобы выполнить соответствующую обработку для набора рассматриваемых аннотаций. После того, как все процессоры возвращаются, apt вызывает каждый процессор поочередно. Если какой-либо процессор, сгенерированный новый исходный файл, рекурсивный раунд apt произойдет. В рекурсивных раундах apt открытие вызывает getProcessorFor на любой фабрике, которая обеспечила процессор в предыдущем раунде, даже если та фабрика не обрабатывает ни одну из текущих аннотаций. Это позволяет фабрике регистрировать слушателя в последующих раундах apt; хотя большинство фабрик просто возвратит AnnotationProcessors.NO_OP в этом случае. После того, как раунд, где никакие новые исходные файлы не сгенерированы, apt, вызовет javac на исходные и сгенерированные исходные файлы. Если никакие процессоры не находятся, или найденные процессоры не обрабатывают аннотации, существующий, вызывающий apt чрезвычайно эквивалентен вызову javac непосредственно на исходных файлах.
Если класс фабрики используется больше чем одним раундом обработки аннотации, класс фабрики загружается однажды, и однажды метод getProcessorFor фабрики вызовут на раунд. Это позволяет фабрике хранить статическое состояние через раунды.
Если опция -factory используется, именованная фабрика является единственной запрошенной.
Раунды способной Обработки
Первый раунд apt анализирует входные исходные файлы, выполняет процедуру открытия, и вызывает получающиеся процессоры аннотации. Второй раунд apt анализирует новые исходные файлы, произведенные первым раундом (если любой), выполняет процедуру открытия на тех новых файлах, и вызывает получающиеся процессоры аннотации. Аналогично, если второй раунд произвел новые исходные файлы, третий раунд анализирует новый источник, открытие выполнений, и т.д. раунды apt продолжаются, пока никакие новые исходные файлы не сгенерированы. Наконец, после последнего раунда, по умолчанию инструмент apt выполнит javac на исходных и сгенерированных исходных файлах.
Процессоры аннотации или фабрики могут зарегистрировать слушателей для конца круглого использования метода addListener в среде. Инструмент вызывает зарегистрированных слушателей после того, как все процессоры аннотации для того раунда работали к завершению. Слушатель является переданной информацией о состоянии раунда, такой, как будто любые новые исходные файлы были записаны, если ошибка была повышена, и если справедливым, завершенным вокруг, был последний раунд. Слушатели могут использоваться, чтобы выписать запаздывание концов файлов, когда вся обработка аннотации завершилась. Тот же самый класс может реализовать и AnnotationProcessor и интерфейсы RoundCompleteListener, таким образом, тот же самый объект может служить в обоих контекстах.
Код возврата
Если javac будет вызван то после последнего apt вокруг, код возврата apt будет кодом возврата javac, компилирующего те файлы. Если javac не будет вызван, то у apt будет 0 статусов выхода, если ни о каких ошибках не сообщил, или инструмент непосредственно или процессорами. Работа на уродливых или неполных исходных файлах в и себя не достаточна, чтобы заставить apt иметь ненулевой статус выхода.
Зеркальный API представляет конструкции исходного кода преимущественно через интерфейс Declaration и его иерархию подынтерфейсов в пакете com.sun.mirror.declaration. Declaration представляет элемент программы, такой как пакет, класс, или метод, и обычно соответствует непосредственный определенному фрагменту исходного кода. Declarations является структурами, которые могут быть аннотированы.
Типы представляются интерфейсом TypeMirror и его иерархией подынтерфейсов в пакете com.sun.mirror.type. Типы включают типы примитивов, класс и интерфейсные типы, выстраивают типы, вводят переменные, и подстановочные типы.
API делает все возможное различить объявления и типы. Это старше значащее для универсальных типов, где единственное объявление может определить всю семью типов. Например, объявление класса java.util.Set соответствует
параметризованный тип java.util.Set<String>
параметризованный тип java.util.Set<Number>
параметризованный тип java.util.Set<T> для некоторого типа T кроме String или Number
необработанный тип java.util.Set.
У объявления есть комментарии документа, исходная позиция, модификаторы, и аннотации. У объявления могут быть различные виды имен (простой, квалифицированный). Более определенные подклассы объявления обеспечивают дополнительную информацию, подходящую для той конструкции. Например, объявления класса обеспечивают доступ к конструкторам и суперклассу. У объявления для enum есть метод, чтобы обеспечить константы enum.
TypeMirror s используется, чтобы смоделировать типы возврата, типы параметра, и т.д., в исходном коде. TypeMirror для ссылочного типа обеспечивает отображение от типа до соответствующего объявления; например от типа зеркально отражают для java.util.Set<String> к объявлению для java.util.Set.
Вы знаете о Debian Усовершенствованный Инструмент Упаковки? Да.
Как процессор аннотации сравнивается с doclet? У этих двух объектов, конечно, есть некоторые общие черты; оба используют разовые сборкой отражающие API, чтобы обработать исходный код. Однако, зеркальные API, используемые в процессорах аннотации лучшая модель текущая система типов языка программирования Java. Кроме того, по умолчанию процессор (ы) аннотации, чтобы работать определяется аннотациями, существующими в исходном коде, а не только на механизме, аналогичном опции -doclet. Другими словами, вместо того, чтобы выполнить единственный фиксированный doclet, apt динамически выбирает потенциально многократные процессоры, чтобы работать.
Как я могу обработать аннотации на локальные переменные? Аннотации на локальные переменные невидимы, так как иерархия объявления не моделирует структуру программы в методе или конструкторе.
Почему там отдельная фабрика и интерфейсы процессора в com.sun.mirror.apt? Было бы возможно объединить определение, как обработать и управление, когда обработать; однако, мы хотим отличать и разделять два шага интерфейсами процессора и фабрикой.
Каково зеркало? Где-нибудь Вы находите отражение. В отражающем программировании зеркальный проект поддерживает непротиворечивое разделение между представляемыми объектами и объектами, делающими представление.
То, почему аннотации были фабрикой, поддерживает и опции, которые фабрика поддерживает возвращенный методами вместо того, чтобы быть закодированной как аннотации на класс фабрики? Реализация интерфейса является обычным механизмом, чтобы указать, что у класса есть требуемая возможность, такая как обеспечение индикации относительно того, какие аннотации это обрабатывает. Нет никакого механизма языка, чтобы потребовать класса, который будет аннотироваться определенным типом аннотации. Поэтому, в то время как было бы технически возможно закодировать такую информацию в аннотациях, делая так испытает недостаток в безопасности типов только наличия методов в интерфейсе.
Я не знаком с посетителями, я должен использовать их? Шаблон "посетитель" является одним из стандартных образцов в "Бригаде Четырех" книг Шаблонов разработки. Образец обеспечивает мощный механизм, чтобы вызвать зависимую от типа работу, явно не тестируя на тип. Однако, использование посетителей не обязательно.