web-dev-qa-db-fra.com

Comment analyser les classes pour les annotations?

J'ai une application web de servlets plain jane, et certaines de mes classes ont les annotations suivantes:

@Controller
@RequestMapping(name = "/blog/")
public class TestController {
..

}

Maintenant, lorsque mes applications de servlet démarrent, je voudrais obtenir une liste de toutes les classes qui ont l'annotation @Controller, puis obtenir la valeur de l'annotation @RequestMapping et l'insérer dans un dictionnaire.

Comment puis-je faire ceci?

J'utilise également Guice et Guava, mais je ne sais pas si cela a des aides liées aux annotations.

17
loyalflow

Vous pouvez utiliser la bibliothèque Reflections en lui donnant le package et l'annotation que vous recherchez.

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();
}

Bien sûr, le fait de placer toutes vos servlets dans le même paquet rend cela un peu plus facile. Vous pouvez également rechercher les classes qui ont l'annotation RequestMapping à la place, car c'est celle dont vous cherchez à obtenir une valeur.

38
Jacob Schoen

La recherche d'annotations est très difficile. Vous devez en fait traiter tous les emplacements de chemin de classe et essayer de trouver des fichiers correspondant aux classes Java (* .class).

Je suggère fortement d'utiliser un framework qui offre de telles fonctionnalités. Vous pouvez par exemple jeter un œil à Scannotation .

5
chkal

Si vous utilisez Spring,

Il a quelque chose appelé une classe AnnotatedTypeScanner.
Cette classe utilise en interne

ClassPathScanningCandidateComponentProvider

Cette classe a le code pour l'analyse réelle des ressources classpath. Pour ce faire, il utilise les métadonnées de classe disponibles au moment de l'exécution.

On peut simplement étendre cette classe ou utiliser la même classe pour la numérisation. Voici la définition du constructeur.

   /**
     * 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;
    }
3
swayamraina

Essayez le maïs-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
   }
}

Dépendance du module Maven:

<dependency>
    <groupId>net.sf.corn</groupId>
    <artifactId>corn-cps</artifactId>
    <version>1.0.1</version>
</dependency>

visitez le site https://sites.google.com/site/javacornproject/corn-cps pour plus d'informations

2
Serhat