日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring 注解编程之 AnnotationMetadata

發布時間:2024/4/17 javascript 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring 注解编程之 AnnotationMetadata 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在上篇文章 Spring 注解編程之模式注解 中我們講到 Spring 模式注解底層原理,依靠 AnnotationMetadata 接口判斷是否存在指定元注解。

這篇文章我們主要深入 AnnotationMetadata,了解其底層原理。

Spring 版本為 5.1.8-RELEASE

AnnotationMetadata 結構

使用 IDEA 生成 AnnotationMetadata 類圖,如下:

AnnotationMetadata 存在兩個實現類分別為 StandardAnnotationMetadata與 AnnotationMetadataReadingVisitor。StandardAnnotationMetadata主要使用 Java 反射原理獲取元數據,而 AnnotationMetadataReadingVisitor 使用 ASM 框架獲取元數據。

Java 反射原理大家一般比較熟悉,而 ASM 技術可能會比較陌生,下面主要篇幅介紹 AnnotationMetadataReadingVisitor 實現原理。

基于 AnnotationMetadata#getMetaAnnotationTypes方法,查看兩者實現區別。

AnnotationMetadataReadingVisitor

ASM 是一個通用的 Java 字節碼操作和分析框架。它可以用于修改現有類或直接以二進制形式動態生成類。 ASM 雖然提供與其他 Java 字節碼框架如 Javassist,CGLIB類似的功能,但是其設計與實現小而快,且性能足夠高。

Spring 直接將 ASM 框架核心源碼內嵌于 Spring-core中,目前 Spring 5.1 使用 ASM 7 版本。

ASM 框架簡單應用

Java 源代碼經過編譯器編譯之后生成了 .class 文件。

Class文件是有8個字節為基礎的字節流構成的,這些字節流之間都嚴格按照規定的順序排列,并且字節之間不存在任何空隙,對于超過8個字節的數據,將按 照Big-Endian的順序存儲的,也就是說高位字節存儲在低的地址上面,而低位字節存儲到高地址上面,其實這也是class文件要跨平臺的關鍵,因為 PowerPC架構的處理采用Big-Endian的存儲順序,而x86系列的處理器則采用Little-Endian的存儲順序,因此為了Class文 件在各中處理器架構下保持統一的存儲順序,虛擬機規范必須對起進行統一。

Class 文件中包含類的所有信息,如接口,字段屬性,方法,在內部這些信息按照一定規則緊湊排序。ASM 框會以文件流的形式讀取 class 文件,然后解析過程中使用觀察者模式(Visitor),當解析器碰到相應的信息委托給觀察者(Visitor)。

使用 ASM 框架首先需要繼承 ClassVisitor,完成解析相應信息,如解析方法,字段等。

然后使用 ClassReader 讀取類文件,然后再使用 ClassReader#accpet 接受 ClassVisitor。

輸出結果為:

com/spring/learning/customizescanning/asm/Person extends java/lang/Object {Lcom/spring/learning/customizescanning/asm/ASMAnnotation; Ljava/lang/String; name class org.objectweb.asm.TypeI age class org.objectweb.asm.Type<init>()Vadd(II)IgetName()Ljava/lang/String;setName(Ljava/lang/String;)VgetAge()IsetAge(I)V }

可以看到 ClassVisitor 相應方法可以用來解析類的相關信息,這里我們主要關注解析類上注解信息。解析注解將會在 ClassVisitor#visitAnnotation完成解析。 該方法返回了一個 AnnotationVisitor 對象,其也是一個 Visitor 對象。后續解析器會繼續調用 AnnotationVisitor內部方法進行再次解析。

以上實現采用 ASM Core API ,而 ASM 框架還提供 Tree API 用法。具體用法參考:https://asm.ow2.io/

AnnotationMetadataReadingVisitor#getMetaAnnotationTypes 源碼解析

AnnotationMetadataReadingVisitor#getMetaAnnotationTypes 方法實現非常簡單,直接從 metaAnnotationMap 根據注解類名稱獲取其上面所有元注解。注解相關信息解析由 AnnotationMetadataReadingVisitor#visitAnnotation 完成。

在 visitAnnotation 方法中,metaAnnotationMap當做構造參數傳入了 AnnotationAttributesReadingVisitor 對象中,metaAnnotationMap會在這里面完成賦值。

AnnotationAttributesReadingVisitor#visitEnd 將會排除 java.lang.annotation 下的注解,然后通過遞歸調用 recursivelyCollectMetaAnnotations獲取元注解,不斷將元注解置入 metaAnnotationMap中。

最后使用 UML 時序圖中,概括以上調用流程。

Spring 4 之后版本才有遞歸查找元注解的方法。各位同學可以翻閱 Spring3 的版本作為比較,可以看出 Spring 的代碼功能也是逐漸迭代升級的。

StandardAnnotationMetadata

StandardAnnotationMetadata 主要使用 Java 反射原理獲取相關信息。在 Spring 中封裝很多了反射工具類用于操作。

StandardAnnotationMetadata#getMetaAnnotationTypes 通過使用 Spring 工具類 AnnotatedElementUtils.getMetaAnnotationTypes方法獲取。源碼調用比較清晰,各位同學可以自行翻閱理解,可以參考下面時序圖理解,這里不再敘述。

總結

本文介紹了 AnnotationMetadata兩種實現方案,一種基于 Java 反射,另一種基于 ASM 框架。

兩種實現方案適用于不同場景。StandardAnnotationMetadata基于 Java 反射,需要加載類文件。而 AnnotationMetadataReadingVisitor基于 ASM 框架無需提前加載類,所以適用于 Spring 應用掃描指定范圍內模式注解時使用。

擴展閱讀

  • 實例分析JAVA CLASS的文件結構
  • asm 官方文檔
  • 『Spring Boot 編程思想』-小馬哥
  • 另外歡迎加入 Java 極客技術知識星球,獲取最新 Java 技術。

    轉載于:https://www.cnblogs.com/goodAndyxublog/p/11218619.html

    總結

    以上是生活随笔為你收集整理的Spring 注解编程之 AnnotationMetadata的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。