Как я могу изучить все исходное дерево с помощью процессора аннотаций?

У меня есть много классов обработчиков, которые обрабатывают определенные типы сообщений. Чтобы зарегистрировать все эти обработчики, мне нужно знать, какие из них существуют. В настоящее время все они аннотированы определенной аннотацией, и я использую процессор аннотаций Java 6, чтобы получить их все, и создаю класс Register, который содержит экземпляр каждого из аннотированных типов.

Это отлично работает, если все дерево строится сразу, но если строится только один из аннотированных классов (например, когда я сохраняю файл в Eclipse), процессор видит только этот тип и строит неполный регистр. Как я могу изучить другие типы в этом сценарии?


person Tavian Barnes    schedule 14.05.2012    source источник
comment
Какой процессор аннотаций вы используете?   -  person Garrett Hall    schedule 16.05.2012
comment
Один, который я написал сам, используя API Java 6 (расширение javax.annotation.processing.AbstractProcessor)   -  person Tavian Barnes    schedule 16.05.2012
comment
+1. На основании моих собственных исследований этого нет, но если это так, мне бы очень хотелось об этом узнать.   -  person John Ericksen    schedule 17.05.2012
comment
Мне интересно, перекомпилирует ли eclipse все исходное дерево при экспорте apk?   -  person John Ericksen    schedule 17.05.2012


Ответы (2)


На данный момент я решил это достаточно хорошо. То, что я сделал, - это небольшая хитрость, но в основном для каждого аннотированного класса, который я вижу, я добавляю его имя в HashSet. Затем я использую Filer.getResource (), чтобы открыть файл, в котором я записал все ранее замеченные аннотированные классы, и также добавить их в HashSet. Затем я создаю класс регистров и записываю весь HashSet в тот же ресурс с помощью Filer.createResource (). Это вызовет проблемы, если я удалю аннотированный тип, поскольку он все равно будет записан в этот файл, но я могу просто очистить проект или удалить этот файл, чтобы решить эту проблему.

РЕДАКТИРОВАТЬ: Кроме того, я считаю, что передача соответствующих «исходных элементов» в Filer.createSource () должна позволить Eclipse правильно отслеживать эти зависимости, но это не так. Возможно, это ошибка Eclipse.

person Tavian Barnes    schedule 22.05.2012
comment
у вас случайно есть этот код где-нибудь? Мне интересен ваш подход. - person John Ericksen; 25.05.2012
comment
Это код компании, но если я когда-нибудь напишу что-то подобное для личного проекта, он будет доступен. - person Tavian Barnes; 26.05.2012
comment
Я написал для этого общую библиотеку. Я нашел эту страницу, потому что моя библиотека страдает той же проблемой ... - person Sławek; 11.10.2012
comment
Это круто, я всегда хотел этим заниматься, но у меня никогда не было времени. Я попробую. - person Tavian Barnes; 11.10.2012

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

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

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

person Old Pro    schedule 17.05.2012
comment
Это код Android, и похоже, что большинство этих фреймворков не работают на Android; в любом случае, я бы хотел избежать сканирования пути к классам, если это вообще возможно. Если бы я пошел по маршруту RegisterHandlerClass, как именно это помогло бы? Как я могу заставить эти классы зарегистрировать соответствующий класс обработчика, не имея, так сказать, регистра регистров? - person Tavian Barnes; 17.05.2012
comment
Если проблема в том, что классы обработчиков не загружаются, моя идея RegisterHandlerClass тоже не сработает. Вместо этого вы можете создать один файл ресурсов для каждого класса обработчика и поместить их все в один каталог, а затем просто сканировать этот каталог во время выполнения. - person Old Pro; 17.05.2012