Как сканировать классы для аннотаций?
У меня есть обычное веб-приложение сервлетов jane, а некоторые из моих классов имеют следующие аннотации:
@Controller
@RequestMapping(name = "/blog/")
public class TestController {
..
}
Теперь, когда мои приложения сервлета запускаются, я хотел бы получить список всех классов с аннотацией @Controller, а затем получить значение аннотации @RequestMapping и вставить его в словарь.
Как я могу это сделать?
Я также использую Guice и Guava, но не уверен, что у них есть помощники, связанные с аннотациями.
Ответы
Ответ 1
Вы можете использовать Reflections library, предоставив ему пакет и Аннотацию, которую вы ищете.
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(Controller.class);
for (Class<?> controller : annotated) {
RequestMapping request = controller.getAnnotation(RequestMapping.class);
String mapping = request.name();
}
Конечно, размещение всех ваших сервлетов в одном пакете делает это немного проще. Также вы можете захотеть искать классы, у которых есть аннотация RequestMapping
, так как это тот, с которого вы хотите получить значение.
Ответ 2
Сканирование аннотаций очень сложно. Фактически вам нужно обработать все места пути и попытаться найти файлы, соответствующие классам Java (*.class).
Я настоятельно рекомендую использовать инфраструктуру, обеспечивающую такую функциональность. Вы можете, например, посмотреть Scannotation.
Ответ 3
Попробуйте кукурузу-cps
List<Class<?>> classes = CPScanner.scanClasses(new PackageNameFilter("net.sf.corn.cps.*"),new ClassFilter().appendAnnotation(Controller.class));
for(Class<?> clazz: classes){
if(clazz.isAnnotationPresent(RequestMapping.class){
//This is what you want
}
}
Зависимость модуля Maven:
<dependency>
<groupId>net.sf.corn</groupId>
<artifactId>corn-cps</artifactId>
<version>1.0.1</version>
</dependency>
зайдите на сайт https://sites.google.com/site/javacornproject/corn-cps для получения дополнительной информации
Ответ 4
Если вы используете Spring,
В нем есть нечто, называемое классом AnnotatedTypeScanner
.
Этот класс внутренне использует
ClassPathScanningCandidateComponentProvider
Этот класс имеет код для фактического сканирования ресурсов classpath. Это делается с помощью метаданных класса, доступных во время выполнения.
Можно просто расширить этот класс или использовать тот же класс для сканирования. Ниже приведено определение конструктора.
/**
* Creates a new {@link AnnotatedTypeScanner} for the given annotation types.
*
* @param considerInterfaces whether to consider interfaces as well.
* @param annotationTypes the annotations to scan for.
*/
public AnnotatedTypeScanner(boolean considerInterfaces, Class<? extends Annotation>... annotationTypes) {
this.annotationTypess = Arrays.asList(annotationTypes);
this.considerInterfaces = considerInterfaces;
}
Ответ 5
Вместо непосредственного использования рефлексии вы можете сделать намного проще, используя библиотеки AOP из Google Guice. AOP является распространенным способом реализации сквозных задач приложения, таких как ведение журнала/трассировка, обработка транзакций или проверка разрешений.
Вы можете узнать больше об этом здесь: https://github.com/google/guice/wiki/AOP
Ответ 6
Если вы можете получить доступ к своим .class файлам, вы можете получить аннотацию, используя класс, как показано ниже:
RequestMapping reqMapping =
TestController.class.getAnnotation(RequestMapping.class);
String name = reqMapping.name(); //now name shoud have value as "/blog/"
Также убедитесь, что ваши классы отмечены RetentionPolicy
как RUNTIME
@Retention(RetentionPolicy.RUNTIME)