搜尋
首頁Javajava教程取得指定包下所有自訂註解

取得指定包下所有自訂註解

Jun 23, 2017 pm 03:26 PM
指定註解自訂獲取

Reflections 透過掃描 classpath,索引元數據,允許在運行時查詢這些元數據,也可以保存收集項目中多個模組的元數據資訊。

使用Reflections快速掃描指定包下自訂的Controller和RequestMapping兩個註解,先去掃描加了@Controller註解的類,接著獲取這些類下面加了@RequestMapping註解的方法,然後透過Java的反射invoke方法去呼叫加了RequestMapping註解的方法並輸出註解上的資訊。

Maven 專案導入

<dependency>
    <groupid>org.reflections</groupid>
    <artifactid>reflections</artifactid>
    <version>0.9.10</version>
</dependency>

annotation套件下面自訂了兩個註解。

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

在model套件下面定義了一個存放RequestMapping註解方法的物件

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

service套件下面定義了幾個類,其中有兩個類別使用了自訂的Controller註解

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

util套件下面定義了一個工具類,來對套件進行掃描獲取自定義註解的類別與方法

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> getRequestMappingMethod(String packageName) {
        Reflections reflections = new Reflections(packageName);
        Set<class>> classesList = reflections.getTypesAnnotatedWith(Controller.class);

        // 存放url和ExecutorBean的对应关系
        Map<string> mapp = new HashMap<string>();
        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;
    }

}</string></string></class></string>

#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> mmap = new HashMap<string>();
        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();
        }
    }
}</string></string></class>

運行得到:

取得指定包下所有自訂註解

其他

  1. 使用Reflections 可以查詢以下元資料資訊:

    Reflections 依賴Google 的Guava函式庫和Javassist 函式庫。

  • 得到某個類型的所有子類型

  • #獲得標記了某個註解的所有類型/成員變量,支援註解參數匹配。

  • 使用正規表示式獲得所有符合的資源檔案

  • #獲得所有特定簽章(包括參數,參數註解,傳回值)的方法

  • 使用註解修飾了類別/方法/成員變數等之後,這些註解不會自己生效,必須由這些註解的開發者提供相應的工具來提取並處理註解資訊(當然​​,只有當定義註解時使用了@Retention(RetentionPolicy.RUNTIME)修飾,JVM才會在裝載class檔案時提取保存在class檔案中的註解,該註解才會在運行時可見,這樣我們才能夠解析).

  • Java使用Annotation介面來代表程式元素前面的註解,該介面是所有註解的父介面。

  • java5在java.lang.reflect套件下新增了用AnnotatedElement介面代表程式中可以接受註解的程式元素.

  • AnnotatedElement介面的實作類別有:Class(類別元素)、Field(類別的成員變數元素)、Method(類別的方法元素)、Package(套件元素),每一個實作類別代表了一個可以接受註解的程式元素類型。

  • 這樣, 我們只需要獲取到Class、 Method、 Filed等這些實作了AnnotatedElement介面的類別的實例,透過該實例物件呼叫該類別中的方法(AnnotatedElement介面中抽象方法的重寫) 就可以獲得我們想要的註解資訊了。

  • 得到Class類別的實例有三種方法:

    • #利用物件呼叫getClass()方法來取得Class實例

    • 利用Class類別的靜態的forName()方法,使用類別名稱取得Class實例

    • #運用.class的方式取得Class實例,如:類別名.class

  • AnnotatedElement介面提供的抽象方法(在該介面的實作類別中重寫了這些方法):

    • T getAnnotation(Class annotationClass)< T extends Annotation>為泛型參數聲明,表明A的類型只能是Annotation類型或是Annotation的子類別。
      功能:傳回該程式元素上存在的、指定類型的註解,如果該類型的註解不存在,則傳回null

    • Annotation[] getAnnotations()
      功能:傳回此元素上存在的所有註解,包括沒有顯示定義在該元素上的註解(繼承得到的)。 (如果此元素沒有註釋,則傳回長度為零的陣列。)

    • T getDeclaredAnnotation(Class annotationClass)
      功能:這是Java8新增的方法,此方法傳回直接修飾該程式元素、指定類型的註解(忽略繼承的註解)。如果該類型的註解不存在,則傳回null.

    • Annotation[] getDeclaredAnnotations()
      功能:傳回直接存在於此元素上的所有註解,該方法將忽略繼承的註釋。 (如果沒有註解直接存在於此元素上,則傳回長度為零的一個陣列。)

    • boolean isAnnotationPresent(Class extends Annotation>annotationClass)
      功能:判斷判斷該程式元素上是否存在指定類型的註解,如果存在則傳回true,否則回傳false。

    • <T extends Annotation> T[] getAnnotationsByTpye(Class annotationClass)
      功能: 因為java8增加了重複註解功能,因此需要使用該方法獲得修飾該程式元素、指定類型的多個註解。

    • T[] getDeclaredAnnotationsByTpye(ClassannotationClass)
      功能: 因為java8增加了重複註解功能,因此需要使用此方法獲得直接修飾該程式元素、指定類型的多個註解。

    Class提供了getMethod()、getField()以及getConstructor()方法(還有其他方法),這些方法分別取得與方法、領域變數以及建構子相關的信息,這些方法傳回Method、Field 以及Constructor型別的物件。

    以上是取得指定包下所有自訂註解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?Mar 17, 2025 pm 05:46 PM

    本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

    如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?Mar 17, 2025 pm 05:45 PM

    本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

    如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?Mar 17, 2025 pm 05:44 PM

    本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

    如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?Mar 17, 2025 pm 05:43 PM

    本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

    Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Mar 17, 2025 pm 05:35 PM

    Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

    See all articles

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    AI Hentai Generator

    AI Hentai Generator

    免費產生 AI 無盡。

    熱門文章

    R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
    3 週前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳圖形設置
    3 週前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.如果您聽不到任何人,如何修復音頻
    3 週前By尊渡假赌尊渡假赌尊渡假赌
    WWE 2K25:如何解鎖Myrise中的所有內容
    4 週前By尊渡假赌尊渡假赌尊渡假赌

    熱工具

    Atom編輯器mac版下載

    Atom編輯器mac版下載

    最受歡迎的的開源編輯器

    ZendStudio 13.5.1 Mac

    ZendStudio 13.5.1 Mac

    強大的PHP整合開發環境

    SublimeText3漢化版

    SublimeText3漢化版

    中文版,非常好用

    WebStorm Mac版

    WebStorm Mac版

    好用的JavaScript開發工具

    VSCode Windows 64位元 下載

    VSCode Windows 64位元 下載

    微軟推出的免費、功能強大的一款IDE編輯器