Java中的Lombok使用及工作原理詳解
1.Lombok簡(jiǎn)介
大概的意思:Lombok是一個(gè)Java庫(kù),能自動(dòng)插入編輯器并構(gòu)建工具,簡(jiǎn)化Java開(kāi)發(fā)。通過(guò)添加注解的方式,不需要為類(lèi)編寫(xiě)getter或eques方法,同時(shí)可以自動(dòng)化日志變量。官網(wǎng)鏈接
簡(jiǎn)而言之:Lombok能以簡(jiǎn)單的注解形式來(lái)簡(jiǎn)化java代碼,提高開(kāi)發(fā)人員的開(kāi)發(fā)效率。
2.Lombok使用
使用Lombok需要的開(kāi)發(fā)環(huán)境Java+Maven+IntelliJ IDEA或者Eclipse(安裝Lombok Plugin)
2.1添加maven依賴(lài)
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.4</version> <scope>provided</scope> </dependency>
2.2安裝插件
使用Lombok還需要插件的配合,我使用開(kāi)發(fā)工具為idea,這里只講解idea中安裝lombok插件,使用eclipse和myeclipse的小伙伴和自行g(shù)oogle安裝方法。 打開(kāi)idea的設(shè)置,點(diǎn)擊Plugins,點(diǎn)擊Browse repositories,在彈出的窗口中搜索lombok,然后安裝即可
2.3解決編譯時(shí)出錯(cuò)問(wèn)題
編譯時(shí)出錯(cuò),可能是沒(méi)有enable注解處理器。
Annotation Processors > Enable annotation processing
。設(shè)置完成之后程序正常運(yùn)行。
2.4示例
下面舉兩個(gè)栗子,看看使用lombok和不使用的區(qū)別。
創(chuàng)建一個(gè)用戶(hù)類(lèi)
不使用Lombok
public class User implements Serializable { private static final long serialVersionUID = -8054600833969507380L; private Integer id; private String username; private Integer age; public User() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } User user = (User) o; return Objects.equals(id, user.id) && Objects.equals(username, user.username) && Objects.equals(age, user.age); } @Override public int hashCode() { return Objects.hash(id, username, age); } }
使用Lombok
@Data public class User implements Serializable { private static final long serialVersionUID = -8054600833969507380L; private Integer id; private String username; private Integer age; }
編譯源文件,然后反編譯class文件,反編譯結(jié)果如下圖。
說(shuō)明@Data注解在類(lèi)上,會(huì)為類(lèi)的所有屬性自動(dòng)生成setter/getter、equals、canEqual、hashCode、toString方法,如為final屬性,則不會(huì)為該屬性生成setter方法。
自動(dòng)化日志變量
@Slf4j @RestController @RequestMapping(("/user")) public class UserController { @GetMapping("/getUserById/{id}") public User getUserById(@PathVariable Integer id) { User user = new User(); user.setUsername("風(fēng)清揚(yáng)"); user.setAge(21); user.setId(id); if (log.isInfoEnabled()) { log.info("用戶(hù) {}", user); } return user; } }
通過(guò)反編譯可以看到@Slf4j注解生成了log日志變量(嚴(yán)格意義來(lái)說(shuō)是常量),無(wú)需去聲明一個(gè)log就可以在類(lèi)中使用log記錄日志。
2.5常用注解
下面介紹一下常用的幾個(gè)注解:
- @Setter 注解在類(lèi)或字段,注解在類(lèi)時(shí)為所有字段生成setter方法,注解在字段上時(shí)只為該字段生成setter方法。
- @Getter 使用方法同上,區(qū)別在于生成的是getter方法。
- @ToString 注解在類(lèi),添加toString方法。
- @EqualsAndHashCode 注解在類(lèi),生成hashCode和equals方法。
- @NoArgsConstructor 注解在類(lèi),生成無(wú)參的構(gòu)造方法。
- @RequiredArgsConstructor 注解在類(lèi),為類(lèi)中需要特殊處理的字段生成構(gòu)造方法,比如final和被@NonNull注解的字段。
- @AllArgsConstructor 注解在類(lèi),生成包含類(lèi)中所有字段的構(gòu)造方法。
- @Data 注解在類(lèi),生成setter/getter、equals、canEqual、hashCode、toString方法,如為final屬性,則不會(huì)為該屬性生成setter方法。
- @Slf4j 注解在類(lèi),生成log變量,嚴(yán)格意義來(lái)說(shuō)是常量。private static final Logger log = LoggerFactory.getLogger(UserController.class);
3.Lombok工作原理
在Lombok使用的過(guò)程中,只需要添加相應(yīng)的注解,無(wú)需再為此寫(xiě)任何代碼。自動(dòng)生成的代碼到底是如何產(chǎn)生的呢?
核心之處就是對(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)了該接口,對(duì)反射熟悉的朋友應(yīng)該都會(huì)很熟悉這種解析方式。
編譯時(shí)解析 編譯時(shí)解析有兩種機(jī)制,分別簡(jiǎn)單描述下:
1)Annotation Processing Tool
apt自JDK5產(chǎn)生,JDK7已標(biāo)記為過(guò)期,不推薦使用,JDK8中已徹底刪除,自JDK6開(kāi)始,可以使用Pluggable Annotation Processing API來(lái)替換它,apt被替換主要有2點(diǎn)原因:
- api都在com.sun.mirror非標(biāo)準(zhǔn)包下
- 沒(méi)有集成到j(luò)avac中,需要額外運(yùn)行
2)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)生作用的具體流程如下:
1.javac對(duì)源代碼進(jìn)行分析,生成了一棵抽象語(yǔ)法樹(shù)(AST)
2.運(yùn)行過(guò)程中調(diào)用實(shí)現(xiàn)了“JSR 269 API”的Lombok程序
3.此時(shí)Lombok就對(duì)第一步驟得到的AST進(jìn)行處理,找到@Data注解所在類(lèi)對(duì)應(yīng)的語(yǔ)法樹(shù)(AST),然后修改該語(yǔ)法樹(shù)(AST),增加getter和setter方法定義的相應(yīng)樹(shù)節(jié)點(diǎn)
4.javac使用修改后的抽象語(yǔ)法樹(shù)(AST)生成字節(jié)碼文件,即給class增加新的節(jié)點(diǎn)(代碼塊)
通過(guò)讀Lombok源碼,發(fā)現(xiàn)對(duì)應(yīng)注解的實(shí)現(xiàn)都在HandleXXX中,比如@Getter注解的實(shí)現(xiàn)在HandleGetter.handle()。還有一些其它類(lèi)庫(kù)使用這種方式實(shí)現(xiàn),比如Google Auto、Dagger等等。
4.Lombok的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
(1)能通過(guò)注解的形式自動(dòng)生成構(gòu)造器、getter/setter、equals、hashcode、toString等方法,提高了一定的開(kāi)發(fā)效率
(2)讓代碼變得簡(jiǎn)潔,不用過(guò)多的去關(guān)注相應(yīng)的方法
(3)屬性做修改時(shí),也簡(jiǎn)化了維護(hù)為這些屬性所生成的getter/setter方法等
缺點(diǎn):
(1)不支持多種參數(shù)構(gòu)造器的重載
(2)雖然省去了手動(dòng)創(chuàng)建getter/setter方法的麻煩,但大大降低了源代碼的可讀性和完整性,降低了閱讀源代碼的舒適度
到此這篇關(guān)于Java中的Lombok使用及工作原理詳解的文章就介紹到這了,更多相關(guān)Java中的Lombok使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java分析html算法(java網(wǎng)頁(yè)蜘蛛算法示例)
近來(lái)有些朋友在做蜘蛛算法,或者在網(wǎng)頁(yè)上面做深度的數(shù)據(jù)挖掘,下面使用示例2014-03-03java對(duì)象與json對(duì)象間的相互轉(zhuǎn)換的方法
本篇文章主要介紹了java對(duì)象與json對(duì)象間的相互轉(zhuǎn)換的方法,詳細(xì)介紹了json字符串和java對(duì)象相互轉(zhuǎn)換,有興趣的可以了解一下2017-01-01Mybatis通用Mapper(tk.mybatis)的使用
本文主要介紹了Mybatis通用Mapper(tk.mybatis)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07關(guān)于SpringCloud中Ribbon的7種負(fù)載均衡策略解析
這篇文章主要介紹了關(guān)于SpringCloud中Ribbon的7種負(fù)載均衡策略解析,服務(wù)端負(fù)載均衡器的問(wèn)題是,它提供了更強(qiáng)的流量控制權(quán),但無(wú)法滿足不同的消費(fèi)者希望使用不同負(fù)載均衡策略的需求,而使用不同負(fù)載均衡策略的場(chǎng)景確實(shí)是存在的,需要的朋友可以參考下2023-07-07Java數(shù)據(jù)機(jī)構(gòu)中關(guān)于并查集的詳解
并查集是一種樹(shù)型的數(shù)據(jù)結(jié)構(gòu),用于處理一些不相交集合的合并及查詢(xún)問(wèn)題,如果你還不了解并查集,請(qǐng)看接下來(lái)的文章,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值2021-09-09Java實(shí)現(xiàn)利用圖片或視頻生成GIF并發(fā)送微信
這篇文章主要為大家詳細(xì)介紹了Java語(yǔ)言如何利用圖片或視頻實(shí)現(xiàn)生成GIF并發(fā)送微信的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2022-11-11java中List、Array、Map、Set等集合相互轉(zhuǎn)換
這篇文章主要介紹了java中List、Array、Map、Set等集合相互轉(zhuǎn)換的相關(guān)資料,需要的朋友可以參考下2017-05-05java實(shí)現(xiàn)視頻轉(zhuǎn)碼工具類(lèi)
這篇文章主要介紹了java實(shí)現(xiàn)視頻轉(zhuǎn)碼,涉及到工具類(lèi)用到的參數(shù),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01