在Lombok使用的過程中,只需要添加相應的注解,無需再為此寫任何代碼。但是自動生成的代碼到底是如何產生的呢?
核心之處就是對於注解的解析上。JDK5引入了注解的同時,也提供了兩種解析方式。
- 運行時解析
運行時能夠解析的注解,必須將@Retention設置為RUNTIME,這樣就可以通過反射拿到該注解。java.lang,reflect反射包中提供了一個接口AnnotatedElement,該接口定義了獲取注解信息的幾個方法,Class、Constructor、Field、Method、Package等都實現了該接口,對反射熟悉的朋友應該都會很熟悉這種解析方式。
- 編譯時解析
編譯時解析有兩種機制,分別簡單描述下:
1)Annotation Processing Tool
apt自JDK5產生,JDK7已標記為過期,不推薦使用,JDK8中已徹底刪除,自JDK6開始,可以使用Pluggable Annotation Processing API來替換它,apt被替換主要有2點原因:
- api都在com.sun.mirror非標准包下
- 沒有集成到javac中,需要額外運行
2)Pluggable Annotation Processing API
JSR 269自JDK6加入,作為apt的替代方案,它解決了apt的兩個問題,javac在執行的時候會調用實現了該API的程序,這樣我們就可以對編譯器做一些增強,這時javac執行的過程如下:
Lombok本質上就是一個實現了“JSR 269 API”的程序。在使用javac的過程中,它產生作用的具體流程如下:
- javac對源代碼進行分析,生成了一棵抽象語法樹(AST)
- 運行過程中調用實現了“JSR 269 API”的Lombok程序
- 此時Lombok就對第一步驟得到的AST進行處理,找到@Data注解所在類對應的語法樹(AST),然后修改該語法樹(AST),增加getter和setter方法定義的相應樹節點
- javac使用修改后的抽象語法樹(AST)生成字節碼文件,即給class增加新的節點(代碼塊)
拜讀了Lombok源碼,對應注解的實現都在HandleXXX中,比如@Getter注解的實現時HandleGetter.handle()。還有一些其它類庫使用這種方式實現,比如Google Auto、Dagger等等。
原文:https://www.cnblogs.com/heyonggang/p/8638374.html
聲明:此博客為個人學習之用,如與其他作品雷同,純屬巧合,轉載請指明出處!