Heim  >  Artikel  >  Java  >  Rufen Sie alle benutzerdefinierten Anmerkungen unter dem angegebenen Paket ab

Rufen Sie alle benutzerdefinierten Anmerkungen unter dem angegebenen Paket ab

巴扎黑
巴扎黑Original
2017-06-23 15:26:302911Durchsuche

Reflections indiziert Metadaten durch Scannen des Klassenpfads, sodass diese Metadaten zur Laufzeit abgefragt werden können, und kann außerdem Metadateninformationen für mehrere Module im Projekt speichern und sammeln.

Verwenden Sie Reflections, um die benutzerdefinierten Controller- und RequestMapping-Annotationen unter dem angegebenen Paket schnell zu scannen. Scannen Sie zuerst die mit @Controller annotierten Klassen, rufen Sie dann die mit @RequestMapping annotierten Methoden unter diesen Klassen ab und verwenden Sie dann Java Die Methode ruft die mit RequestMapping annotierte Methode auf und gibt die Informationen zur Annotation aus.

Maven-Projektimport

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.10</version>
</dependency>

Zwei Anmerkungen werden unterhalb des Anmerkungspakets angepasst.

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 "";
}

Ein Objekt, das die RequestMapping-Annotationsmethode speichert, ist unter dem Modellpaket definiert

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

Unter dem Servicepaket sind mehrere Klassen definiert, von denen zwei benutzerdefinierte Controller-Annotationen verwenden

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

Unter der Paketklasse util ist ein Tool zum Scannen definiert das Paket, um benutzerdefinierte annotierte Klassen und Methoden zu erhalten

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

}

Das folgende Testpaket ist eine Testklasse

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

Ausführen und abrufen:

Rufen Sie alle benutzerdefinierten Anmerkungen unter dem angegebenen Paket ab

Andere

  1. Verwenden Sie Reflections, um die folgenden Metadateninformationen abzufragen:

    Reflections basiert auf der Guava-Bibliothek und der Javassist-Bibliothek von Google.

  • Alle Untertypen eines bestimmten Typs abrufen

  • Alle mit einer bestimmten Annotation markierten Typen/Mitgliedsvariablen abrufen, Annotationen unterstützen und Parameterübereinstimmung unterstützen .

  • Verwenden Sie reguläre Ausdrücke, um alle passenden Ressourcendateien abzurufen

  • Methode, um alle spezifischen Signaturen abzurufen (einschließlich Parameter, Parameteranmerkungen, Rückgabewerte)

  • Nachdem Sie Annotationen zum Ändern von Klassen/Methoden/Mitgliedsvariablen usw. verwendet haben, werden diese Annotationen von selbst nicht wirksam. Die Entwickler dieser Annotationen müssen entsprechende Tools zum Extrahieren und bereitstellen Verarbeiten Sie sie. Anmerkungsinformationen (natürlich nur, wenn die @Retention(RetentionPolicy.RUNTIME)-Änderung beim Definieren der Anmerkung verwendet wird, extrahiert die JVM die in der Klassendatei gespeicherten Anmerkungen, und die Anmerkung wird sichtbar zur Laufzeit, damit wir analysieren können).

  • Java verwendet die Annotation-Schnittstelle, um die Annotationen vor Programmelementen darzustellen. Diese Schnittstelle ist die übergeordnete Schnittstelle aller Annotationen.

  • Java5 hat die AnnotatedElement-Schnittstelle unter dem Paket java.lang.reflect hinzugefügt, um Programmelemente darzustellen, die Anmerkungen im Programm akzeptieren können.

  • AnnotatedElement Die Implementierungsklassen der Schnittstelle sind: Class (Klassenelement), Field (Mitgliedsvariablenelement der Klasse), Method (Methodenelement der Klasse) und Package (Paketelement). Jede Implementierungsklasse repräsentiert einen Programmelementtyp kann Anmerkungen annehmen.

  • Auf diese Weise müssen wir nur Instanzen von Class, Method, Filed und anderen Klassen abrufen, die die AnnotatedElement-Schnittstelle implementieren, und die Methoden in der Klasse über das Instanzobjekt (abstrakt) aufrufen In der AnnotatedElement-Schnittstellenmethode können wir die gewünschten Anmerkungsinformationen abrufen.

  • Es gibt drei Möglichkeiten, eine Instanz der Class-Klasse zu erhalten:

    • Verwenden Sie das Objekt, um die Methode getClass() aufzurufen um eine Klasseninstanz zu erhalten

    • Verwenden Sie die statische forName()-Methode der Klassenklasse, um die Klasseninstanz mithilfe des Klassennamens abzurufen

    • Verwenden die .class-Methode, um die Klasseninstanz zu erhalten, wie zum Beispiel: Klassenname .class

  • Abstrakte Methoden, die von der AnnotatedElement-Schnittstelle bereitgestellt werden (diese Methoden werden in der Implementierungsklasse davon überschrieben). interface):

    • T getAnnotation(Class< T> annotationClass)< kann nur der Annotation-Typ oder eine Unterklasse von Annotation sein.
      Funktion: Gibt die Anmerkungen des angegebenen Typs zurück, die auf dem Programmelement vorhanden sind. Wenn die Anmerkung dieses Typs nicht vorhanden ist, geben Sie null zurück

    • Annotation[] getAnnotations()
      Funktion: Gibt alle Anmerkungen zurück, die für dieses Element vorhanden sind, einschließlich Anmerkungen, die nicht explizit für dieses Element definiert (geerbt) sind. (Wenn dieses Element keine Annotation hat, wird ein Array mit der Länge Null zurückgegeben.)

    • < T getDeclaredAnnotation(Class < T> annotationClass)
      Funktion: Dies ist eine neue Methode in Java 8. Diese Methode gibt Anmerkungen zurück, die das Programmelement direkt ändern und den Typ angeben (geerbte Anmerkungen werden ignoriert). Wenn Anmerkungen dieses Typs nicht vorhanden sind, geben Sie null zurück.

    • Annotation[] getDeclaredAnnotations()
      Funktion: Gibt alle Anmerkungen zurück, die direkt auf diesem Element vorhanden sind. Diese Methode ignoriert die Vererbung Anmerkung. (Wenn keine Annotation direkt auf diesem Element vorhanden ist, wird ein Array mit der Länge Null zurückgegeben.)

    • boolean isAnnotationPresent(Class annotationClass)
      Funktion: Bestimmung Ob vorhanden ist eine Annotation des angegebenen Typs für das Programmelement. Wenn sie vorhanden ist, wird „true“ zurückgegeben, andernfalls wird „false“ zurückgegeben.

    • <T erweitert Annotation> T[] getAnnotationsByTpye(Class annotationClass)
      Funktion: Da Java8 die wiederholte Annotationsfunktion hinzugefügt hat, müssen Sie diese Methode verwenden, um das geänderte Programmelement abzurufen und der angegebene Typ mehrerer Anmerkungen.

    • T[] getDeclaredAnnotationsByTpye(ClassannotationClass)
      Funktion: Da Java8 die wiederholte Annotationsfunktion hinzufügt, müssen Sie diese Methode zum Abrufen verwenden Direkte Änderung dieses Programmelements, mehrere Anmerkungen des angegebenen Typs.

    Die Klasse stellt die Methoden getMethod(), getField() und getConstructor() (und andere Methoden) bereit, die sich auf Methoden, Domänenvariablen bzw. Konstruktoren beziehen Methoden geben Objekte der Typen Methode, Feld und Konstruktor zurück.

    Das obige ist der detaillierte Inhalt vonRufen Sie alle benutzerdefinierten Anmerkungen unter dem angegebenen Paket ab. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn