Lombok詳細(xì)教程及idea中l(wèi)ombok插件的安裝

一、背景

我們在開發(fā)過程中,通常都會定義大量的JavaBean,然后通過IDE去生成其屬性的構(gòu)造器、getter、setter、equals、hashcode、toString方法,當(dāng)要對某個屬性進(jìn)行改變時,比如命名、類型等,都需要重新去生成上面提到的這些方法,那java中有沒有一種方式能夠避免這種重復(fù)的勞動呢?答案是有,我們來看一下下面這張圖,右面是一個簡單的JavaBean,只定義了兩個屬性,在類上加上了@Data,從左面的結(jié)構(gòu)圖上可以看到,已經(jīng)自動生成了上面提到的方法。


image.png

二、Lombok簡介

Lombok是一個可以通過簡單的注解形式來幫助我們簡化消除一些必須有但顯得很臃腫的Java代碼的工具,通過使用對應(yīng)的注解,可以在編譯源碼的時候生成對應(yīng)的方法。
官方地址:https://projectlombok.org/
github地址:https://github.com/rzwitserloot/lombok

三、Lombok使用

IDEA中添加Lombok插件,File->Setting->Plugins搜索Lombok Plugin,點(diǎn)擊install,安裝完成后重啟IDEA


image.png

備注:如果在上述的安裝過程中無法自動下載,可以選擇本地安裝
插件下載地址:https://plugins.jetbrains.com/plugin/6317-lombok-plugin
具體步驟可以參照 https://blog.csdn.net/shmily_lsl/article/details/80689307 博客
我這邊自己下載的是2016.3版本的
在maven項(xiàng)目的pom.xml中添加依賴

<!-- lombok -->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.2</version>
 <scope>provided</scope>
</dependency>

四、Lombok注解介紹

下面只是介紹了幾個常用的注解,更多的請參見https://projectlombok.org/features/index.html。

1、@Getter / @Setter注解

可以作用在類上和屬性上,放在類上,會對所有的非靜態(tài)(non-static)屬性生成Getter/Setter方法,放在屬性上,會對該屬性生成Getter/Setter方法。并可以指定Getter/Setter方法的訪問級別。當(dāng)然了屬性上面的Getter和Setter的設(shè)置要優(yōu)先于類上面的


image.png

2、@EqualsAndHashCode注解

默認(rèn)情況下,會使用所有非瞬態(tài)(non-transient)和非靜態(tài)(non-static)字段來生成equals和hascode方法,也可以指定具體使用哪些屬性。
1). 此注解會生成equals(Object other) 和 hashCode()方法。
2). 它默認(rèn)使用非靜態(tài),非瞬態(tài)的屬性
3). 可通過參數(shù)exclude排除一些屬性
4). 可通過參數(shù)of指定僅使用哪些屬性
5). 它默認(rèn)僅使用該類中定義的屬性且不調(diào)用父類的方法
6). 可通過callSuper=true解決上一點(diǎn)問題。讓其生成的方法中調(diào)用父類的方法。

3、@ToString

生成toString方法,默認(rèn)情況下,會輸出類名、所有屬性,屬性會按照順序輸出,以逗號分割。

4、@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor

@NoArgsConstructor : 生成一個無參數(shù)的構(gòu)造方法
@AllArgsContructor: ?會生成一個包含所有變量
@RequiredArgsConstructor: 會生成一個包含常量,和標(biāo)識了NotNull的變量的構(gòu)造方法。生成的構(gòu)造方法是私有的private。

5、@Data

@Data相當(dāng)于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode這5個注解的合集。
通過官方文檔,可以得知,當(dāng)使用@Data注解時,則有了@EqualsAndHashCode注解,那么就會在此類中存在equals(Object other) 和 hashCode()方法,且不會使用父類的屬性,這就導(dǎo)致了可能的問題。 比如,有多個類有相同的部分屬性,把它們定義到父類中,恰好id(數(shù)據(jù)庫主鍵)也在父類中,那么就會存在部分對象在比較時,它們并不相等,卻因?yàn)閘ombok自動生成的equals(Object other) 和 hashCode()方法判定為相等,從而導(dǎo)致出錯。
修復(fù)此問題的方法很簡單:
(1)、使用@Getter @Setter @ToString代替@Data并且自定義equals(Object other) 和 hashCode()方法,比如有些類只需要判斷主鍵id是否相等即足矣。
(2)、 或者使用在使用@Data時同時加上@EqualsAndHashCode(callSuper=true)注解。設(shè)置該屬性的話需要保證當(dāng)前類繼承了父類

6、@slf4j

相當(dāng)于在類中書寫了 private static final Logger log = LoggerFactory.getLogger(User.class);

image.png

五、Lombok原理

了解了簡單的使用之后,現(xiàn)在應(yīng)該比較好奇它是如何實(shí)現(xiàn)的。整個使用的過程中,只需要使用注解而已,不需要做其它額外的工作,那玄妙之處應(yīng)該是在注解的解析上。JDK5引入了注解的同時,也提供了兩種解析方式

1、運(yùn)行時解析

運(yùn)行時能夠解析的注解,必須將@Retention設(shè)置為RUNTIME,這樣可以通過反射拿到該注解。java.lang.reflect反射包中提供了一個接口AnnotatedElement,該接口定義了獲取注解信息的幾個方法,Class、Constructor、Field、Method、Package等都實(shí)現(xiàn)了該接口,大部分開發(fā)者應(yīng)該都很熟悉這種解析方式。

boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
<T extends Annotation> T getAnnotation(Class<T> annotationClass);
Annotation[] getAnnotations();
Annotation[] getDeclaredAnnotations();

2、編譯時解析

編譯時解析有兩種機(jī)制,網(wǎng)上很多文章都把它倆搞混了,分別簡單描述一下。

(1)、Annotation Processing Tool

apt自JDK5產(chǎn)生,JDK7已標(biāo)記為過期,不推薦使用,JDK8中已徹底刪除,自JDK6開始,可以使用Pluggable Annotation Processing API來替換它,apt被替換主要有2點(diǎn)原因:
1)、api都在com.sun.mirror非標(biāo)準(zhǔn)包下
2)、沒有集成到j(luò)avac中,需要額外運(yùn)行
apt的更多介紹可以參見這里。

(2)、Pluggable Annotation Processing API

JSR 269,自JDK6加入,作為apt的替代方案,它解決了apt的兩個問題,javac在執(zhí)行的時候會調(diào)用實(shí)現(xiàn)了該API的程序,這樣我們就可以對編譯器做一些增強(qiáng),這時javac執(zhí)行的過程如下:


image.png

??Lombok就是使用這種方式實(shí)現(xiàn)的,有興趣的話可以去看看其Lombok源碼,對應(yīng)注解的實(shí)現(xiàn)都在HandleXXX中,比如@Getter注解的實(shí)現(xiàn)是HandleGetter.handle()。還有一些其它類庫使用這種方式實(shí)現(xiàn),比如Google Auto、Dagger等等。

六、Lombok初學(xué)者使用建議

在剛開始使用Lombok的時候建議大家可以多看看class文件,來加深對你所需要使用注解的理解。


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容