1. 程式人生 > 其它 >Lombok簡介、使用、工作原理、優缺點

Lombok簡介、使用、工作原理、優缺點

1.Lombok簡介

大概的意思:Lombok是一個Java庫,能自動插入編輯器並構建工具,簡化Java開發。通過添加註解的方式,不需要為類編寫getter或eques方法,同時可以自動化日誌變數官網連結

簡而言之:Lombok能以簡單的註解形式來簡化java程式碼,提高開發人員的開發效率。
部落格及原始碼GitHub連結

2.Lombok使用

使用Lombok需要的開發環境Java+Maven+IntelliJ IDEA或者Eclipse(安裝Lombok Plugin)

2.1新增maven依賴

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18
.4</version> <scope>provided</scope> </dependency>

2.2安裝外掛
使用Lombok還需要外掛的配合,我使用開發工具為idea,這裡只講解idea中安裝lombok外掛,使用eclipse和myeclipse的小夥伴和自行google安裝方法。
開啟idea的設定,點選Plugins,點選Browse repositories,在彈出的視窗中搜索lombok,然後安裝即可

2.3解決編譯時出錯問題

編譯時出錯,可能是沒有enable註解處理器。Annotation Processors > Enable annotation processing

。設定完成之後程式正常執行。

2.4示例

下面舉兩個栗子,看看使用lombok和不使用的區別。

建立一個使用者類

不使用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檔案,反編譯結果如下圖。說明@Data註解在類上,會為類的所有屬性自動生成setter/getter、equals、canEqual、hashCode、toString方法,如為final屬性,則不會為該屬性生成setter方法。

自動化日誌變數

@Slf4j
@RestController
@RequestMapping(("/user"))
public class UserController {

    @GetMapping("/getUserById/{id}")
    public User getUserById(@PathVariable Integer id) {
        User user = new User();
        user.setUsername("風清揚");
        user.setAge(21);
        user.setId(id);

        if (log.isInfoEnabled()) {
            log.info("使用者 {}", user);
        }

        return user;
    }

}

通過反編譯可以看到@Slf4j註解生成了log日誌變數(嚴格意義來說是常量),無需去宣告一個log就可以在類中使用log記錄日誌。

2.5常用註解
下面介紹一下常用的幾個註解:

@Setter 註解在類或欄位,註解在類時為所有欄位生成setter方法,註解在欄位上時只為該欄位生成setter方法。
@Getter 使用方法同上,區別在於生成的是getter方法。
@ToString 註解在類,新增toString方法。
@EqualsAndHashCode 註解在類,生成hashCode和equals方法。
@NoArgsConstructor 註解在類,生成無參的構造方法。
@RequiredArgsConstructor 註解在類,為類中需要特殊處理的欄位生成構造方法,比如final和被@NonNull註解的欄位。
@AllArgsConstructor 註解在類,生成包含類中所有欄位的構造方法。
@Data 註解在類,生成setter/getter、equals、canEqual、hashCode、toString方法,如為final屬性,則不會為該屬性生成setter方法。
@Slf4j 註解在類,生成log變數,嚴格意義來說是常量。private static final Logger log = LoggerFactory.getLogger(UserController.class);

3.Lombok工作原理

在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點原因:

  (1)api都在com.sun.mirror非標準包下
  (2)沒有整合到javac中,需要額外執行

2)Pluggable Annotation Processing API

JSR 269自JDK6加入,作為apt的替代方案,它解決了apt的兩個問題,javac在執行的時候會呼叫實現了該API的程式,這樣我們就可以對編譯器做一些增強,javac執行的過程如下:

Lombok本質上就是一個實現了“JSR 269 API”的程式。在使用javac的過程中,它產生作用的具體流程如下:

1.javac對原始碼進行分析,生成了一棵抽象語法樹(AST)
2.執行過程中呼叫實現了“JSR 269 API”的Lombok程式
3.此時Lombok就對第一步驟得到的AST進行處理,找到@Data註解所在類對應的語法樹(AST),然後修改該語法樹(AST),增加getter和setter方法定義的相應樹節點
4.javac使用修改後的抽象語法樹(AST)生成位元組碼檔案,即給class增加新的節點(程式碼塊)

通過讀Lombok原始碼,發現對應註解的實現都在HandleXXX中,比如@Getter註解的實現在HandleGetter.handle()。還有一些其它類庫使用這種方式實現,比如Google AutoDagger等等。

4.Lombok的優缺點

優點:

(1)能通過註解的形式自動生成構造器、getter/setter、equals、hashcode、toString等方法,提高了一定的開發效率
(2)讓程式碼變得簡潔,不用過多的去關注相應的方法
(3)屬性做修改時,也簡化了維護為這些屬性所生成的getter/setter方法等
缺點:

(1)不支援多種引數構造器的過載
(2)雖然省去了手動建立getter/setter方法的麻煩,但大大降低了原始碼的可讀性和完整性,降低了閱讀原始碼的舒適度

ref:lombok