Reflections indexe les métadonnées en analysant le chemin de classe, ce qui permet d'interroger ces métadonnées au moment de l'exécution, et peut également enregistrer et collecter des informations de métadonnées pour plusieurs modules du projet.
Utilisez Reflections pour analyser rapidement les annotations personnalisées Controller et RequestMapping sous le package spécifié. Scannez d'abord les classes annotées avec @Controller, puis obtenez les méthodes annotées avec @RequestMapping sous ces classes, puis utilisez Java L'invocation de réflexion. La méthode appelle la méthode annotée avec RequestMapping et génère les informations sur l'annotation.
Importation de projet Maven
<dependency> <groupId>org.reflections</groupId> <artifactId>reflections</artifactId> <version>0.9.10</version> </dependency>
Deux annotations sont personnalisées sous le package d'annotations.
Controller.java :
package annotationTest.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE)// 注解会在class字节码文件中存在,在运行时可以通过反射获取到 @Retention(RetentionPolicy.RUNTIME)//定义注解的作用目标**作用范围字段、枚举的常量/方法 @Documented//说明该注解将被包含在javadoc中 public @interface Controller { String value() default ""; }
RequestMapping.java
package annotationTest.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface RequestMapping { String value() default ""; /** * 是否为序列号 * * @return */ boolean id() default false; /** * 字段名称 * * @return */ String name() default ""; /** * 字段描述 * * @return */ String description() default ""; }
Un objet stockant la méthode d'annotation RequestMapping est défini sous le package modèle
ExecutorBean.java
package annotationTest.model; import java.lang.reflect.Method; public class ExecutorBean { private Object object; private Method method; public Object getObject() { return object; } public void setObject(Object object) { this.object = object; } public Method getMethod() { return method; } public void setMethod(Method method) { this.method = method; } }
Il existe plusieurs classes définies dans le package de services, dont deux utilisent des annotations de contrôleur personnalisées
SunService.java
package annotationTest.service; import annotationTest.annotation.Controller; import annotationTest.annotation.RequestMapping; @Controller public class SunService { @RequestMapping(id = true, name = "test1", description = "sun测试1", value = "/test1") public void test1() { System.out.println("SunService->test1()"); } @RequestMapping(id = true, name = "test2", description = "sun测试2", value = "/test2") public void test2() { System.out.println("SunService->test2()"); } }
MoonService.java
package annotationTest.service; import annotationTest.annotation.Controller; import annotationTest.annotation.RequestMapping; @Controller public class MoonService { @RequestMapping(id = true, name = "moon测试3", description = "/test3", value = "/test3") public void test3() { System.out.println("MoonService->test3()"); } @RequestMapping(id = true, name = "moon测试4", description = "/test4", value = "/test4") public void test4() { System.out.println("MoonService->test4()"); } }
Stars.java
package annotationTest.service; import annotationTest.annotation.RequestMapping; public class Stars { @RequestMapping(id = true, name = "test1", description = "stars测试1", value = "/test1") public void test1() { System.out.println("Stars->test1()"); } }
Un outil est défini sous la classe du package util pour analyser le package pour obtenir des classes et des méthodes annotées personnalisées
AnnoManageUtil.java
package annotationTest.util; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.Set; import annotationTest.annotation.Controller; import annotationTest.annotation.RequestMapping; import annotationTest.model.ExecutorBean; import org.reflections.Reflections; public final class AnnoManageUtil { /** * 获取指定文件下面的RequestMapping方法保存在mapp中 * * @param packageName * @return */ public static Map<String, ExecutorBean> getRequestMappingMethod(String packageName) { Reflections reflections = new Reflections(packageName); Set<Class<?>> classesList = reflections.getTypesAnnotatedWith(Controller.class); // 存放url和ExecutorBean的对应关系 Map<String, ExecutorBean> mapp = new HashMap<String, ExecutorBean>(); for (Class classes : classesList) { //得到该类下面的所有方法 Method[] methods = classes.getDeclaredMethods(); for (Method method : methods) { //得到该类下面的RequestMapping注解 RequestMapping requestMapping = method.getAnnotation(RequestMapping.class); if (null != requestMapping) { ExecutorBean executorBean = new ExecutorBean(); try { executorBean.setObject(classes.newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } executorBean.setMethod(method); mapp.put(requestMapping.value(), executorBean); } } } return mapp; } }
Le package de test suivant est une classe de test
package annotationTest.test; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.List; import java.util.Map; import annotationTest.annotation.Controller; import annotationTest.annotation.RequestMapping; import annotationTest.model.ExecutorBean; import annotationTest.util.AnnoManageUtil; public class Test { public static void main(String[] args) { List<Class<?>> classesList = null; classesList = AnnoManageUtil.getPackageController("annotationTest.service", Controller.class); Map<String, ExecutorBean> mmap = new HashMap<String, ExecutorBean>(); AnnoManageUtil.getRequestMappingMethod(classesList, mmap); ExecutorBean bean = mmap.get("/test1"); try { bean.getMethod().invoke(bean.getObject()); RequestMapping annotation = bean.getMethod().getAnnotation(RequestMapping.class); System.out.println("注解名称:" + annotation.name() + "\t注解描述:" + annotation.description()); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
Exécutez et obtenez :
Autres
Utilisez Reflections pour interroger les informations de métadonnées suivantes :
Reflections s'appuie sur la bibliothèque Guava et la bibliothèque Javassist de Google.
Obtenir tous les sous-types d'un certain type
Obtenir tous les types/variables membres marqués d'une certaine annotation, prendre en charge les annotations Les paramètres correspondent .
Utilisez des expressions régulières pour obtenir tous les fichiers de ressources correspondants
Méthode pour obtenir toutes les signatures spécifiques (y compris les paramètres, les annotations de paramètres, les valeurs de retour)
Après avoir utilisé des annotations pour modifier des classes/méthodes/variables membres, etc., ces annotations ne prendront pas effet d'elles-mêmes. Les développeurs de ces annotations doivent fournir les outils correspondants pour extraire et. traitez-les. Informations d'annotation (bien sûr, uniquement lorsque la modification @Retention(RetentionPolicy.RUNTIME) est utilisée lors de la définition de l'annotation, la JVM extraira les annotations enregistrées dans le fichier de classe lors du chargement du fichier de classe, et l'annotation sera visible. au moment de l'exécution, afin que nous puissions analyser).
Java utilise l'interface Annotation pour représenter les annotations devant les éléments du programme. Cette interface est l'interface parent de toutes les annotations.
java5 a ajouté l'interface AnnotatedElement sous le package java.lang.reflect pour représenter les éléments de programme pouvant accepter des annotations dans le programme.
AnnotatedElement Les classes d'implémentation de l'interface sont : Class (élément de classe), Field (élément de variable membre de la classe), Method (élément de méthode de la classe) et Package (élément de package). Chaque classe d'implémentation représente un type d'élément de programme qui. peut accepter des annotations.
De cette façon, il nous suffit d'obtenir des instances de Class, Method, Filed et d'autres classes qui implémentent l'interface AnnotatedElement, et d'appeler les méthodes de la classe via l'objet instance (abstrait dans la méthode d'interface AnnotatedElement), nous pouvons obtenir les informations d'annotation souhaitées.
Il existe trois façons d'obtenir une instance de la classe Class :
Utiliser l'objet pour appeler la méthode getClass() pour obtenir une instance de classe
Utilisez la méthode statique forName() de la classe Class pour obtenir l'instance de classe en utilisant le nom de la classe
Utilisez la méthode .class pour obtenir l'instance Class, telle que : nom de classe .class
Méthodes abstraites fournies par l'interface AnnotatedElement (ces méthodes sont remplacées dans la classe d'implémentation de ce interface):
Fonction : Renvoie les annotations du type spécifié qui existent sur l'élément de programme Si l'annotation de ce type n'existe pas, renvoie null
Annotation[] getAnnotations()<.> Fonction : Renvoie toutes les annotations qui existent sur cet élément, y compris les annotations qui ne sont pas explicitement définies sur cet élément (hérité). (Si cet élément n'a pas d'annotation, un tableau de longueur nulle est renvoyé.)
Fonction : Il s'agit d'une nouvelle méthode dans Java 8. Cette méthode renvoie des annotations qui modifient directement l'élément de programme et spécifient le type (en ignorant les annotations héritées). Si les annotations de ce type n'existent pas, renvoyez null.
Fonction : Renvoie toutes les annotations qui existent directement sur cet élément, cette méthode ignorera l'héritage annotation. (Si aucune annotation n'existe directement sur cet élément, un tableau de longueur nulle est renvoyé.)
Fonction : Détermination S'il y a est une annotation du type spécifié sur l'élément de programme Si elle existe, elle renvoie vrai, sinon elle renvoie faux.
<T extends Annotation> T[] getAnnotationsByTpye(Class
Fonction : étant donné que Java8 a ajouté la fonction d'annotation répétée, vous devez utiliser cette méthode pour obtenir l'élément de programme modifié. et le type spécifié plusieurs annotations.
Fonction : étant donné que java8 ajoute la fonction d'annotation répétée, vous devez utiliser cette méthode pour obtenir modification directe Cet élément de programme, plusieurs annotations du type spécifié.
La classe fournit les méthodes getMethod(), getField() et getConstructor() (ainsi que d'autres méthodes), qui sont respectivement liées aux méthodes, aux variables de domaine et aux constructeurs. , ces méthodes renvoient des objets de types Méthode, Champ et Constructeur.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!