1. 簡(jiǎn)介
??Project Lombok makes java a spicier language by adding ‘handlers’ that know how to build and compile simple, boilerplate-free, not-quite-java code.
即Lombok通過(guò)增加一些“處理程序”缀雳,可以讓java變得簡(jiǎn)潔、快速。
??Lombok能通過(guò)注解的方式,在編譯時(shí)自動(dòng)為屬性生成構(gòu)造器、getter/setter蝗敢、equals、hashcode、toString方法力奋。同時(shí)可以自動(dòng)化日志變量。
2. 引入Lombok
??使用Lombok需要的開發(fā)環(huán)境Java+Maven+IntelliJ IDEA或者Eclipse(安裝Lombok Plugin)幽七。
2.1 添加maven依賴
<!-- 引入lombok依賴 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
2.2 idea安裝插件
??打開idea的設(shè)置景殷,點(diǎn)擊Plugins,點(diǎn)擊Browse repositories澡屡,在彈出的窗口中搜索lombok猿挚,然后安裝即可。
2.3 編譯時(shí)出錯(cuò)問(wèn)題
編譯時(shí)出錯(cuò)驶鹉,可能是沒有enable注解處理器绩蜻。在設(shè)置中找到Annotation Processors > Enable annotation processing。設(shè)置完成之后程序正常運(yùn)行室埋。
2.4 常用注解
@Setter :注解在類或字段办绝,注解在類時(shí)為所有字段生成setter方法伊约,注解在字段上時(shí)只為該字段生成setter方法。
@Getter :使用方法同上孕蝉,區(qū)別在于生成的是getter方法屡律。
@ToString :注解在類,生成toStirng方法降淮。
@EqualsAndHashCode :注解在類超埋,生成hashCode和equals方法。
@Data :注解在類佳鳖,生成setter/getter霍殴、equals、canEqual系吩、hashCode来庭、toString方法,如為final屬性穿挨,則不會(huì)為該屬性生成setter方法巾腕。
@NoArgsConstructor :注解在類,生成無(wú)參的構(gòu)造方法絮蒿。
@AllArgsConstructor :注解在類尊搬,生成包含類中所有字段的全參的構(gòu)造方法。
@RequiredArgsConstructor :注解在類土涝,為類中需要特殊處理的字段生成構(gòu)造方法佛寿,比如final和被@NonNull注解的字段。
@Log4j :注解在類上但壮;為類提供一個(gè) 屬性名為log 的 log4j 日志對(duì)象
@Slf4j :注解在類冀泻,生成log變量,嚴(yán)格意義來(lái)說(shuō)是常量蜡饵。private static final Logger log = LoggerFactory.getLogger(UserController.class);
==注意:== 在使用以上注解需要處理參數(shù)時(shí)弹渔,處理方法如下(以@ToString注解為例,其他注解同@ToString注解):
@ToString(exclude="column")
意義:排除column列所對(duì)應(yīng)的元素溯祸,即在生成toString方法時(shí)不包含column參數(shù)肢专;@ToString(exclude={"column1","column2"})
意義:排除多個(gè)column列所對(duì)應(yīng)的元素,其中間用英文狀態(tài)下的逗號(hào)進(jìn)行分割焦辅,即在生成toString方法時(shí)不包含多個(gè)column參數(shù)博杖;@ToString(of="column")
意義:只生成包含column列所對(duì)應(yīng)的元素的參數(shù)的toString方法,即在生成toString方法時(shí)只包含column參數(shù)筷登;剃根;@ToString(of={"column1","column2"})
意義:只生成包含多個(gè)column列所對(duì)應(yīng)的元素的參數(shù)的toString方法,其中間用英文狀態(tài)下的逗號(hào)進(jìn)行分割前方,即在生成toString方法時(shí)只包含多個(gè)column參數(shù)狈醉;
==----------------------------------------------------------------------------------------------------==
- @Cleanup : 可以關(guān)閉流
- @Builder : 被注解的類加個(gè)構(gòu)造者模式
- @Synchronized : 加個(gè)同步鎖
- @SneakyThrows : 等同于try/catch 捕獲異常
- @NonNull : 如果給參數(shù)加個(gè)這個(gè)注解廉油,參數(shù)為null會(huì)拋出空指針異常
- @Value : 注解和@Data類似,區(qū)別在于它會(huì)把所有成員變量默認(rèn)定義為private final修飾苗傅,并且不會(huì)生成set方法娱两。
- @Accessors:注解在類或者屬性上;主要用于控制生成的getter和setter金吗。
??fluent: boolean值,默認(rèn)為false趣竣。此字段主要為控制生成的getter和setter方法前面是否帶get/set
??chain :boolean值摇庙,默認(rèn)false。如果設(shè)置為true遥缕,setter返回的是此對(duì)象卫袒,方便鏈?zhǔn)秸{(diào)用方法
??prefix: 設(shè)置前綴 例如:@Accessors(prefix = “abc”) private String abcAge; 當(dāng)生成get/set方法時(shí),會(huì)把此前綴去掉单匣。
3. 工作原理
lombok的核心之處就是對(duì)于注解的解析上夕凝。
JDK5引入了注解的同時(shí),也提供了兩種解析方式:
- 運(yùn)行時(shí)解析:
?運(yùn)行時(shí)能夠解析的注解户秤,必須將@Retention設(shè)置為RUNTIME码秉,這樣就可以通過(guò)反射拿到該注解。java.lang.reflect反射包中提供了一個(gè)接口AnnotatedElement鸡号,該接口定義了獲取注解信息的幾個(gè)方法转砖,Class、Constructor鲸伴、Field府蔗、Method、Package等都實(shí)現(xiàn)了該接口汞窗。 - 編譯時(shí)解析:
?編譯時(shí)解析有兩種機(jī)制姓赤,分別簡(jiǎn)單描述下:- Annotation Processing Tool
apt自JDK5產(chǎn)生,JDK7已標(biāo)記為過(guò)期仲吏,不推薦使用不铆,JDK8中已徹底刪除,自JDK6開始裹唆,可以使用Pluggable Annotation Processing API來(lái)替換它狂男,apt被替換主要有2點(diǎn)原因:
api都在com.sun.mirror非標(biāo)準(zhǔn)包下;沒有集成到j(luò)avac中品腹,需要額外運(yùn)行岖食。 -
Pluggable Annotation Processing API
JSR 269自JDK6加入,作為apt的替代方案舞吭,它解決了apt的兩個(gè)問(wèn)題,javac在執(zhí)行的時(shí)候會(huì)調(diào)用實(shí)現(xiàn)了該API的程序郑诺,這樣我們就可以對(duì)編譯器做一些增強(qiáng)敢会,javac執(zhí)行的過(guò)程如下:
在這里插入圖片描述
Lombok本質(zhì)上就是一個(gè)實(shí)現(xiàn)了“JSR 269 API”的程序。在使用javac的過(guò)程中忠寻,它產(chǎn)生作用的具體流程如下:
- javac對(duì)源代碼進(jìn)行分析,生成了一棵抽象語(yǔ)法樹(AST)存和;
- 運(yùn)行過(guò)程中調(diào)用實(shí)現(xiàn)了“JSR 269 API”的Lombok程序奕剃;
- 此時(shí)Lombok就對(duì)第一步驟得到的AST進(jìn)行處理,找到@Data注解所在類對(duì)應(yīng)的語(yǔ)法樹(AST)捐腿,然后修改該語(yǔ)法樹(AST)纵朋,增加getter和setter方法定義的相應(yīng)樹節(jié)點(diǎn);
- javac使用修改后的抽象語(yǔ)法樹(AST)生成字節(jié)碼文件茄袖,即給class增加新的節(jié)點(diǎn)(代碼塊)操软。通過(guò)讀Lombok源碼,發(fā)現(xiàn)對(duì)應(yīng)注解的實(shí)現(xiàn)都在HandleXXX中宪祥,比如@Getter注解的實(shí)現(xiàn)在HandleGetter.handle()聂薪。還有一些其它類庫(kù)使用這種方式實(shí)現(xiàn),比如Google Auto蝗羊、Dagger等等藏澳。
- Annotation Processing Tool
4. Lombok的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 能通過(guò)注解的形式自動(dòng)生成構(gòu)造器、getter/setter耀找、equals笆载、hashcode、toString等方法涯呻,提高了一定的開發(fā)效率凉驻;
- 讓代碼變得簡(jiǎn)潔,不用過(guò)多的去關(guān)注相應(yīng)的方法复罐;
- 屬性做修改時(shí)涝登,也簡(jiǎn)化了維護(hù)為這些屬性所生成的getter/setter方法等;
缺點(diǎn):
- 不支持多種參數(shù)構(gòu)造器的重載效诅;胀滚;
- 雖然省去了手動(dòng)創(chuàng)建getter/setter方法的麻煩,但大大降低了源代碼的可讀性和完整性乱投,降低了閱讀源代碼的舒適度咽笼;