Lombok工作原理
在Lombok使用的過程中,只需要添加相應(yīng)的注解,無需再為此寫任何代碼辕近。自動生成的代碼到底是如何產(chǎn)生的呢?
核心之處就是對于注解的解析上匿垄。JDK5引入了注解的同時移宅,也提供了兩種解析方式。
1運行時解析
運行時能夠解析的注解椿疗,必須將@Retention設(shè)置為RUNTIME吞杭,這樣就可以通過反射拿到該注解。java.lang.reflect反射包中提供了一個接口AnnotatedElement变丧,該接口定義了獲取注解信息的幾個方法,Class绢掰、Constructor痒蓬、Field、Method滴劲、Package等都實現(xiàn)了該接口攻晒,對反射熟悉的朋友應(yīng)該都會很熟悉這種解析方式。
2編譯時解析
編譯時解析有兩種機(jī)制班挖,分別簡單描述下:
a)Annotation Processing Tool
apt自JDK5產(chǎn)生鲁捏,JDK7已標(biāo)記為過期,不推薦使用萧芙,JDK8中已徹底刪除给梅,自JDK6開始,可以使用Pluggable Annotation Processing API來替換它双揪,apt被替換主要有2點原因:
[1]api都在com.sun.mirror非標(biāo)準(zhǔn)包下
[2]沒有集成到j(luò)avac中动羽,需要額外運行
b)Pluggable Annotation Processing API
JSR 269自JDK6加入,作為apt的替代方案渔期,它解決了apt的兩個問題运吓,javac在執(zhí)行的時候會調(diào)用實現(xiàn)了該API的程序渴邦,這樣我們就可以對編譯器做一些增強(qiáng),javac執(zhí)行的過程如下:
Lombok本質(zhì)上就是一個實現(xiàn)了“JSR 269 API”的程序拘哨。在使用javac的過程中谋梭,它產(chǎn)生作用的具體流程如下:
1.javac對源代碼進(jìn)行分析,生成了一棵抽象語法樹(AST)
2.運行過程中調(diào)用實現(xiàn)了“JSR 269 API”的Lombok程序
3.此時Lombok就對第一步驟得到的AST進(jìn)行處理倦青,找到@Data注解所在類對應(yīng)的語法樹(AST)瓮床,然后修改該語法樹(AST),增加getter和setter方法定義的相應(yīng)樹節(jié)點
4.javac使用修改后的抽象語法樹(AST)生成字節(jié)碼文件姨夹,即給class增加新的節(jié)點(代碼塊)
通過讀Lombok源碼纤垂,發(fā)現(xiàn)對應(yīng)注解的實現(xiàn)都在HandleXXX中,比如@Getter注解的實現(xiàn)在HandleGetter.handle()磷账。還有一些其它類庫使用這種方式實現(xiàn)峭沦,比如Google Auto、Dagger等等逃糟。
Lombok使用
下面介紹一下常用的幾個注解:
@Setter?注解在類或字段吼鱼,注解在類時為所有字段生成setter方法,注解在字段上時只為該字段生成setter方法绰咽。
@Getter?使用方法同上菇肃,區(qū)別在于生成的是getter方法。
@ToString?注解在類取募,添加toString方法琐谤。調(diào)用toString()方法,可以輸出實體類中所有屬性的值玩敏。
@EqualsAndHashCode?注解在類斗忌,生成hashCode和equals方法。
@NoArgsConstructor?注解在類旺聚,生成無參的構(gòu)造方法织阳。
@RequiredArgsConstructor?注解在類,為類中需要特殊處理的字段生成構(gòu)造方法砰粹,比如final和被@NonNull注解的字段唧躲。
@AllArgsConstructor?注解在類,生成包含類中所有字段的構(gòu)造方法碱璃。
@Data?注解在類弄痹,生成setter/getter、equals嵌器、canEqual界酒、hashCode、toString嘴秸、EqualsAndHashCode毁欣、RequiredArgsConstrutor方法庇谆,如為final屬性,則不會為該屬性生成setter方法凭疮。
@Slf4j?注解在類饭耳,生成log變量,嚴(yán)格意義來說是常量执解。private static final Logger log = LoggerFactory.getLogger(UserController.class);
接下來我們編輯一個實體類Student寞肖,添加幾個屬性,最后在類上添加@Data屬性衰腌,這個注解可以幫我們在.class文件中生成類中所有屬性的get/set方法新蟆、equals、canEqual右蕊、hashCode琼稻、toString方法等。
這是之前沒有加@Data注解的寫法的對比會發(fā)現(xiàn)加了注解的代碼少了get/set方法饶囚。
下面創(chuàng)建一個類進(jìn)行測試帕翻,發(fā)現(xiàn)沒有g(shù)et/set方法的實體類加了注解以后也是可以正常調(diào)用get/set方法的。