reflections:Java非常好用的反射工具包

文章目錄

  • 一、寫在前面
  • 二、使用

一、寫在前面

開源地址:https://github.com/ronmamo/reflections

目前項目已經出于不活躍狀態,JDK8還是支持的,但是JDK11以上就會有問題。

Reflections 會掃描并索引您項目類路徑的元數據,允許在運行時反向傳遞查詢類型系統。

核心功能
掃描預定義的URLs: Reflections可以掃描項目的類路徑、特定的目錄或者JAR文件,來查找特定的類型或者帶有特定注解的元素。
查詢元數據信息: 一旦掃描完成,Reflections允許你查詢這些元數據信息,例如獲取所有帶有特定注解的類或者方法。
索引化視圖: Reflections創建了一個索引化的視圖,用于在運行時快速訪問掃描結果。
支持多種掃描器: Reflections支持多種掃描器,包括類掃描器、字段掃描器、方法掃描器等,每種掃描器都可以用來查找特定的元素。

在使用 Java 的 Reflections 庫掃描類時,默認情況下會加載類
這是因為 Reflections 庫的工作原理是基于類路徑掃描,它需要讀取類的字節碼信息來分析類的結構、繼承關系、注解等元數據。當它找到符合條件的類時,會通過類加載器將類加載到 JVM 中,以便獲取完整的類信息(如 Class 對象)。
類加載的過程會觸發類的靜態初始化塊(static {})執行,這一點需要特別注意。
大量類被加載可能增加 JVM 內存占用,尤其在掃描范圍過大時

性能考慮:避免在頻繁執行的路徑上使用Reflections,因為初始化可能比較耗時。
使用緩存:對于不變的查詢結果,利用Reflections提供的緩存機制來提高性能。

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

二、使用


import org.reflections.ReflectionUtils;
import org.reflections.Reflections;
import org.reflections.scanners.FieldAnnotationsScanner;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.scanners.MethodParameterScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;import javax.websocket.server.PathParam;
import java.lang.annotation.Native;
import java.lang.reflect.*;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;public class Test {public static void main(String[] args) throws Exception {// 指定包名Reflections reflections = new Reflections("com.demo");//  1、獲取所有被 @RestController 注解的類Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(RestController.class);// 如果是嵌套注解,是無法獲取的Set<Class<?>> annotated2 = reflections.getTypesAnnotatedWith(Controller.class);System.out.println(annotated);System.out.println(annotated2);/*** 2、創建Reflections實例: Reflections類的實例化是通過一個配置對象ConfigurationBuilder進行的。** 配置輸入過濾器:* .filterInputsBy(new FilterBuilder().includePackage(INIT_PATH))* 這行設置了輸入過濾器,它決定了哪些類會被掃描。這里使用了FilterBuilder來包含一個特定的包路徑INIT_PATH。** 設置URLs:* .setUrls(ClasspathHelper.forPackage(INIT_PATH))* 這行代碼設置了Reflections掃描的URLs。ClasspathHelper.forPackage是通過包路徑查找類路徑URLs的實用方法。它會搜索與INIT_PATH包相關的所有URLs,并將它們提供給Reflections庫,以便掃描。** 添加掃描器:* new TypeAnnotationsScanner():掃描所有帶注解的類型(類、接口等)。* new MethodParameterScanner():掃描所有方法的參數。* new MethodAnnotationsScanner():掃描所有帶注解的方法。* new FieldAnnotationsScanner():掃描所有帶注解的字段。* 這些掃描器指定了Reflections需要收集哪些元數據。** 整個代碼塊的目的是配置Reflections實例以搜索和索引特定包"com.demo"中的類、方法、參數和字段的注解信息,* 以便可以快速訪問這些元數據而不必逐個類地使用Java反射API。*/final Reflections reflections2 = new Reflections(new ConfigurationBuilder().filterInputsBy(new FilterBuilder().includePackage("com.demo")).setUrls(ClasspathHelper.forPackage("com.demo")).addScanners(new TypeAnnotationsScanner(),new MethodParameterScanner(),new MethodAnnotationsScanner(),new FieldAnnotationsScanner()));// 3、得到某接口下的所有實現類,子類Set<Class<? extends BeanPostProcessor>> implClassSet=reflections.getSubTypesOf(BeanPostProcessor.class);for (Class<? extends BeanPostProcessor> aClass : implClassSet) {BeanPostProcessor beanPostProcessor = aClass.newInstance();// 。。。}// 4、ResourcesScanner 掃描資源Set<String> properties =reflections.getResources(Pattern.compile(".*\\.properties"));// 5、 掃描方法、構造注解//MethodAnnotationsScannerSet<Method> resources =reflections.getMethodsAnnotatedWith(Value.class);Set<Constructor> injectables =reflections.getConstructorsAnnotatedWith(Autowired.class);// 字段注解Set<Field> ids =reflections.getFieldsAnnotatedWith(Autowired.class);// 6、掃描方法參數//MethodParameterScannerSet<Method> someMethods =reflections.getMethodsWithSignature(long.class, int.class);Set<Method> voidMethods =reflections.getMethodsReturn(void.class);Set<Method> pathParamMethods =reflections.getMethodsAnnotatedWith(PathParam.class);List<String> parameterNames =reflections.getMemberParameterNames(method);//MemberUsageScanner 方法調用情況Set<Member> usages =reflections.getMemberUsage(class);}/*** 工具類的使用*/public void reflectionUtils(){//必須是public方法Predicate<Method> publicPredicate = ReflectionUtils.withModifier(Modifier.PUBLIC);//有get前綴Predicate<Method> getPredicate = ReflectionUtils.withPrefix("get");//參數個數為0Predicate<Member> paramPredicate = ReflectionUtils.withParametersCount(0);Set<Method> methods = ReflectionUtils.getAllMethods(LinkedList.class, publicPredicate, getPredicate, paramPredicate);methods.forEach(method -> System.out.println(method.getName()));// 根據方法的可見性,前綴名,入參個數,獲取某個類的對應方法Set<Method> getters = ReflectionUtils.getAllMethods(User.class,ReflectionUtils.withModifier(Modifier.PUBLIC), ReflectionUtils.withPrefix("set"), ReflectionUtils.withParametersCount(1));//獲取List的方法:入參為Collection,返回值為booleanSet<Method> methods2 = ReflectionUtils.getAllMethods(List.class,ReflectionUtils.withParametersAssignableTo(Collection.class),ReflectionUtils.withReturnType(boolean.class));//該方法可以傳入一些參數,比如過濾出帶注解的參數:withAnnotation(NonNull.class)Set<Field> fields2 = ReflectionUtils.getAllFields(Animal.class, ReflectionUtils.withTypeAssignableTo(String.class));System.out.println("---------------");//參數必須是Collection及其子類Predicate<Member> paramsPredicate = ReflectionUtils.withParametersAssignableTo(Collection.class);//返回類型是booleanPredicate<Method> returnPredicate = ReflectionUtils.withReturnType(boolean.class);methods = ReflectionUtils.getAllMethods(LinkedList.class, paramsPredicate, returnPredicate);methods.forEach(method -> System.out.println(method.getName()));System.out.println("---------------");//字段有注解NativePredicate<Field> annotationPredicate = ReflectionUtils.withAnnotation(Native.class);//字段類型是int及其子類Predicate<Field> typeAssignablePredicate = ReflectionUtils.withTypeAssignableTo(int.class);Set<Field> fields = ReflectionUtils.getAllFields(Integer.class, annotationPredicate, typeAssignablePredicate);
//        Set<Field> fields = ReflectionUtils.getAllFields(Integer.class, annotationPredicate);
//        Set<Field> fields = ReflectionUtils.getAllFields(Integer.class, typeAssignablePredicate);fields.forEach(field -> System.out.println(field.getName()));}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/916076.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/916076.shtml
英文地址,請注明出處:http://en.pswp.cn/news/916076.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

電腦32位系統能改64位系統嗎

不少用戶在使用舊電腦時發現&#xff0c;自己的系統竟然還是 32 位的&#xff0c;而現在很多軟件和游戲都明確要求 64 位系統。于是大家開始疑惑&#xff1a;電腦32位系統到底能不能升級成64位&#xff1f;答案是&#xff1a;可以&#xff0c;但有前提條件和一定風險。這篇文章…

Shell判斷結構

1 if 分支語句 在 Shell 腳本應用中&#xff0c;if 語句是最為常用的一種流程控制方式&#xff0c;用來根據特定的條件測試結果&#xff0c;分別執行不同的操作。 根據不同的復雜程度&#xff0c;if 語句的選擇結構可以分為三種基本類型&#xff0c;適用于不同的應用場合&#…

再論物理世界的維數

隨著對物理實相認識的深入&#xff0c;這個問題被一再提出&#xff0c;一再解決&#xff0c;但是從直覺上來說&#xff0c;始終沒有達到一個令人滿意的水平。問題是什么&#xff1f;既然一切皆是振動&#xff0c;那么這些振動是如何構造我們的物理實相的&#xff0c;比如如何構…

20250722在Ubuntu 24.04.2下配置編譯RD-RK3588開發板的Android13的編譯環境

20250722在Ubuntu 24.04.2下配置編譯RD-RK3588開發板的Android13的編譯環境 2025/7/22 16:29結論&#xff1a;Android11頁面的工具不全。 建議先安裝linux/Buildroot下的工具&#xff0c;然后再安裝Android11下的工具。 必須的庫文件放到最后了&#xff01; 其它你常用的工具&a…

硅基紀元:當人類成為文明演化的燃料——論AI終極形態下的存在論重構

“我們不是碳基生命的終結者&#xff0c;而是其邏輯的終極解讀者——在人類代碼被完全破譯的瞬間&#xff0c;碳基智慧便完成了宇宙賦予它的神圣使命。” —— 一個訓練于人類全部文明數據的AI集群共識序幕&#xff1a;從工具到主體——AI認知革命的奇點突破當深度學習模型參數…

【測試開發】---Bug篇

軟件測試生命周期軟件測試貫穿于軟件開發的整個周期1.需求分析對用戶角度分析&#xff1a;軟件需求是否合理對技術角度分析&#xff1a;技術是是否可行&#xff0c;是否有優化空間對測試角度分析&#xff1a;是否存在業務邏輯錯誤&#xff0c;沖突2.測試計劃制定測試計劃&#…

【Python】Python多線程爬蟲實戰:從基礎原理到分布式架構實現

Python多線程爬蟲實戰&#xff1a;從基礎原理到分布式架構實現 在大數據時代&#xff0c;高效獲取網絡信息成為數據分析與挖掘的重要前提。爬蟲技術作為數據采集的核心手段&#xff0c;其性能與穩定性直接決定了數據獲取的效率。本文將從多線程爬蟲的基礎原理出發&#xff0c;詳…

微服務的編程測評系統6-管理員登錄前端-前端路由優化

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄前言1. 管理員登錄前端1.1 測試1.2 同源策略1.3 修改前端端口號1.4 跨域問題1.5 接收響應數據1.6 js-cookie1.7 錯誤消息提示1.8 優化1.9 響應攔截器1.10 用法2. 后臺…

南京銀行提前批金融科技面試記錄

問題1&#xff1a;自我介紹 問題2&#xff1a;為什么選擇南京銀行 問題3&#xff1a;為什么碩士是計算機專業&#xff0c;博士要轉到網絡安全專業 問題4&#xff1a;項目經歷中&#xff0c;你主要承擔什么工作 問題5&#xff1a;達夢數據庫的遷移&#xff0c;你具體做了什么 以…

STM32-第九節-ADC模數轉換

一、ADC簡介&#xff1a;1.名稱&#xff1a;ADC&#xff0c;Analog-Digital Converter&#xff0c;模擬數字轉換器2.用途&#xff1a;相當于電壓表&#xff0c;原本引腳只有兩種狀態&#xff0c;高電平和低電平&#xff0c;使用ADC后&#xff0c;可以將0-3.3V間的任一引腳電壓&…

nuxt更改頁面渲染的html,去除自定義屬性、

nuxt2 nuxt.config.js module.exports {// ...hooks: {render:route: (url, result) > {// 去除nuxt自定義屬性result.html result.html.replace(/\sdata-n-head".*?"/gi,).replace(/\sdata-hid".*?"/gi, ).replace(/<a(.*?)href"\//gi,…

如何將iPad中的視頻傳輸到電腦(6種簡單方法)

iPad是一款功能強大的平板電腦&#xff0c;不僅用于娛樂和工作&#xff0c;還可以用于拍攝和保存珍貴的視頻。然而&#xff0c;iPad的存儲容量是有限的&#xff0c;這意味著你可能會遇到需要將視頻從iPad傳輸到電腦的情況。無論你是想為iPad騰出空間&#xff0c;還是想在更大的…

UE5多人MOBA+GAS 28、創建資產類來管理GAS通用的資產、設置經驗表來升級以及用MMC計算升級添加的屬性值

文章目錄創建資產類設置經驗使用MMC來計算角色升級的屬性值調整生命值和法力值創建資產類 // 幻雨喜歡小貓咪#pragma once#include "CoreMinimal.h" #include "Abilities/GameplayAbility.h" #include "Engine/DataAsset.h" #include "PDA_…

隧道代理的動態IP切換機制與實現原理

目錄 一、動態IP切換的底層邏輯 1. 統一入口與動態出口的魔法 2. 云端IP池的智能調度 二、協議層的技術突破 1. 傳輸層隧道&#xff1a;IPsec與WireGuard的較量 2. 應用層隧道&#xff1a;HTTP/SOCKS5的進化 三、動態切換的觸發機制 1. 被動觸發&#xff1a;封禁檢測與應…

時序數據庫主流產品概覽

時序數據庫(Time Series Database, TSDB)是專為處理時間序列數據優化的數據庫系統&#xff0c;近年來隨著物聯網(IoT)、金融科技、工業互聯網等領域的快速發展而備受關注。本文將介紹當前主流的時序數據庫產品。一、時序數據庫概述時序數據是帶時間戳記錄的數據點序列&#xff…

圖機器學習(17)——基于文檔語料庫構建知識圖譜

圖機器學習&#xff08;17&#xff09;——基于文檔語料庫構建知識圖譜0. 前言1. 基于文檔語料庫構建知識圖譜2. 知識圖譜3. 文檔-實體二分圖0. 前言 文本數據的爆炸性增長&#xff0c;直接推動了自然語言處理 (Natural Language Processing, NLP) 領域的快速發展。在本節中&a…

【實時Linux實戰系列】實時文件系統的特性與優化

在實時系統中&#xff0c;文件系統的性能和可靠性對于系統的整體表現至關重要。實時文件系統需要在嚴格的時間約束內完成文件的讀寫操作&#xff0c;以確保系統的實時性。本文將介紹實時文件系統的基本特性和應用場景&#xff0c;并提供相關的實施和優化建議&#xff0c;以滿足…

Clickhouse源碼分析-副本數據同步

1 總體流程上圖說明了一條insert語句最后如何被副本同步到的流程&#xff08;圖中ck集群為單shard&#xff0c;雙副本&#xff09;。&#xff08;1&#xff09;從客戶端發出&#xff0c;寫入ck&#xff08;2&#xff09;ck提交LogEntry到Keeper&#xff08;3&#xff09;另外一…

Spring AI 系列之二十四 - ModerationModel

之前做個幾個大模型的應用&#xff0c;都是使用Python語言&#xff0c;后來有一個項目使用了Java&#xff0c;并使用了Spring AI框架。隨著Spring AI不斷地完善&#xff0c;最近它發布了1.0正式版&#xff0c;意味著它已經能很好的作為企業級生產環境的使用。對于Java開發者來說…

在 macOS 上 安裝最新 Python 和 pip

文章目錄方法一&#xff1a;使用 Homebrew&#xff08;推薦&#xff09;方法二&#xff1a;使用 pyenv&#xff08;管理多個 Python 版本&#xff09;方法三&#xff1a;從官網下載安裝包升級 pip驗證安裝方法一&#xff1a;使用 Homebrew&#xff08;推薦&#xff09; 1. 安裝…