Table of contents
1 關於 Lombok
一般黎講,我地多數會喺啲只有 properties 既 VO(value object)、DTO(data transfer object)、entity classes 上使用 Lombok。
呢啲 classes 有以下既特徵:
- 有好多 properties,如
private
或 protected
既非 static
properties,但絕對唔會係 public
(除非冇跟到 best practice)
- 至少有一個 constructor
- 容許我地建立多個 objects(換言之呢個 class 唔可以係 singleton)
- 每個 property 都有對應既 getter(
get
開頭,冇 parameter,有 return type,如 String getName()
),而如果係 mutable class 就會有埋 setter(set
開頭,有 parameter,void
return type,如 void setName(String name)
),呢啲 getters/setters 都係 public
,應該佔呢個 class 既 methods 既大部分,而 getters/setters 其實用 Eclipse 都可以 gen 到出黎,所以被稱為 boilerplate code
1.1 唔用 Lombok 既例子
1public class Person {
2 private String firstName;
3 private String lastName;
4
5 public String getFirstName() {
6 return firstName;
7 }
8
9 public String getLastName() {
10 return lastName;
11 }
12
13 public void setFirstName(String firstName) {
14 this.firstName = firstName;
15 }
16
17 public void setLastName(String lastName) {
18 this.lastName = lastName;
19 }
20}
1.2 用左 Lombok 既例子
以下例子用左 @Getter
同 @Setter
黎為所有 properties 去 gen getters 同 setters,以及 @FieldDefaults(level = PRIVATE)
去為所有 properties 加上 private
既 access modifier。
1@Getter
2@Setter
3@FieldDefaults(level = PRIVATE)
4public class Person {
5 String firstName;
6 String lastName;
7}
2 喺 Eclipse 安裝 Lombok
Double click 個 JAR 檔,選擇 Eclipse 既安裝路徑,然後完成安裝。
最後,重新開啟 Eclipse。
3 正式使用 Lombok
3.1 添加 Maven dependencies
pom.xml
裡面需要以下 dependency:
1<dependency>
2 <groupId>org.projectlombok</groupId>
3 <artifactId>lombok</artifactId>
4 <version>1.18.24</version>
5 <scope>provided</scope>
6</dependency>
7
3.2 寫 Java code
1@Getter
2@Setter
3@FieldDefaults(level = PRIVATE)
4public class Person {
5 String firstName;
6 String lastName;
7}
3.3 喺 Eclipse 查看 Outline
Eclipse 會話畀我地知我地既 properties 實際上係 private
同埋呢個 class 有咩 methods,我地應該會見到對應既 getters 同 setters 都已經 gen 左出黎。
雖然個 class 既 source code 睇唔到有 getters/setters,但因為 Lombok 已經喺 compile time 幫我地 gen 左 code,所以其實同我地自己寫既 code 冇任何分別。
3.4 運用 Lombok generate 出黎既 code
試驗一下 Lombok gen 出黎同自己寫既有冇分別,毫不意外地 Eclipse 正常 compile 到,冇報任何 error,而運行程式都可以正常咁 call 到 setters 去 set properties、call 到 getters 去 get 返出黎。
4 更多 Lombok annotations
Lombok 有以下既 annotations 都好有用:
Lombok annotation | 描述 | 參考 |
---|
@Getter | 根據 properties 去 gen getters | 官網 |
@Setter | 根據 properties 去 gen setters,可以加上 chain = true 去令 setters 既 return type 由 void 改為個 property 屬於既 class,從而支援 method chaining(new Person().setFirstName("Michael").setLastName("Chung") ) | 官網 |
@ToString | 根據 properties 去 gen toString method | 官網 |
@EqualsAndHashCode | 根據 properties 去 gen equals 及 hashCode methods | 官網 |
@Data | 懶人包——包括曬 @ToString 、@EqualsAndHashCode 、@Getter 、@Setter 及 @RequiredArgsConstructor | 官網 |
@Value | 懶人包(immutable 版)——包括曬 @ToString 、@EqualsAndHashCode 、@AllArgsConstructor 、@FieldDefaults(makeFinal = true, level = PRIVATE) 及 @Getter ,而呢個 class 都會係 final | 官網 |
@Builder | 根據 properties 去 gen 一個 inner class 叫 XxxBuilder (如 PersonBuilder ),builder class 裡面有非 set 開頭既 setters 同一個 build method,畀我地用 builder 黎 construct objects,從而做到 builder pattern,亦支援 method chaining | 官網 |
@FieldDefaults | 為啲冇 access modifier(default)既 properties 加上 access modifier,如 private | 官網 |
@NoArgsConstructor | Gen 一個冇 argument 既 constructor,如 public Person() {} | 官網 |
@RequiredArgsConstructor | 根據 class 內 final 或 @NonNull 既 properties 去 gen 一個 constructor | 官網 |
@AllArgsConstructor | Gen 一個有齊所有 properties 既 constructor | 官網 |
@Slf4j | Gen 一個 static 既 Slf4j log object 出黎,for 出 log 用(一般都係用 log.debug 或 log.info 代替 System.out.println ,用 log.warn 或 log.error 代替 System.err.println ),而個 project 需要 org.slf4j 既 slf4j-api 及 ch.qos.logback 既 logback-classic 兩個 dependencies。另外,我地可以喺 main/resources 度加個 logback.xml 檔黎設定 Logback,例子喺下面 | 官網 |
logback.xml
:
1<?xml version="1.0" encoding="UTF-8"?>
2<configuration>
3
4 <property name="LOG_FOLDER" value="logs" />
5 <property name="LOG_FILE" value="app" />
6 <property name="STYLE_LOG_PATTERN" value="%magenta(%d{yyyy-MM-dd HH:mm:ss.SSS}) %highlight(%-5level) [%-5t] %cyan(%-50.50replace(%replace(%caller{1}){'Caller.*?at ', 'at '}){'(\r)?\n', ''}) - %msg%n" />
7 <property name="PLAIN_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%-5t] %-50.50replace(%replace(%caller{1}){'Caller.*?at ', 'at '}){'(\r)?\n', ''} - %msg%n" />
8
9
10
11 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
12 <layout class="ch.qos.logback.classic.PatternLayout">
13 <Pattern>${STYLE_LOG_PATTERN}</Pattern>
14 </layout>
15 </appender>
16
17
18
19 <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
20 <file>${LOG_FOLDER}/${LOG_FILE}.log</file>
21 <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
22 <Pattern>${PLAIN_LOG_PATTERN}</Pattern>
23 </encoder>
24
25 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
26 <!-- rollover daily -->
27 <fileNamePattern>${LOG_FOLDER}/archived/${LOG_FILE}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
28 <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
29 <maxFileSize>10MB</maxFileSize>
30 </timeBasedFileNamingAndTriggeringPolicy>
31 </rollingPolicy>
32 </appender>
33
34
35
36 <root level="info">
37 <appender-ref ref="STDOUT" />
38 <appender-ref ref="FILE" />
39 </root>
40
41</configuration>
5 Lombok 配置檔
我地可以喺 project root folder 新增一個 lombok.config
檔,然後根據上述官網提及既 config properties 黎設定呢個 project 既 Lombok。
lombok.config
檔既例子:
lombok.getter.noIsPrefix=true
lombok.accessors.chain=true
以上 config 帶黎既效果:
@Getter
為 property boolean exist
gen 出黎既 getter 就會係 getExist
而唔係 isExist
@Setter
為 property boolean exist
gen 出黎既 setter 既 return type 就會係個 property 屬於既 class 而唔係 void
6 Spring Boot Maven Plugin:JAR 檔排除 Lombok
如果我地喺 Spring Boot projects 裡面用 spring-boot-maven-plugin
,我地唔需要 Lombok dependency 出現喺最終果個 artifact JAR 檔裡面。
咁係因為 compile 階段已經 generate 曬啲 code,所以最終果個 artifact JAR 檔裡面既 Lombok JAR 檔就再冇利用價值。
不過,用 Maven <dependency>
既 <scope>provided</scope>
係唔會 work,因為我地喺 Maven package
phase 裡面用左 Spring Boot Maven plugin 既 repackage
goal,佢依然係會將所有 dependencies 既 JAR 檔打包喺 BOOT-INF/lib
裡面。
要解決呢個問題,我地就要自行配置 Spring Boot Maven plugin 去 exclude 佢:
1<build>
2 <plugins>
3 <plugin>
4 <groupId>org.springframework.boot</groupId>
5 <artifactId>spring-boot-maven-plugin</artifactId>
6 <executions>
7 <execution>
8 <goals>
9 <goal>repackage</goal>
10 </goals>
11 </execution>
12 </executions>
13 <configuration>
14 <excludes>
15 <exclude>
16 <groupId>org.projectlombok</groupId>
17 <artifactId>lombok</artifactId>
18 </exclude>
19 </excludes>
20 </configuration>
21 </plugin>
22 </plugins>
23</build>
參考資料:
7 Java 14 既 record
Java 14 新加既 record
type 嘗試做緊部分 Lombok 既功能。
record
會 gen 到以下既野:
equals
method
hashCode
method
toString
method
private
access modifier
final
modifier
public
constructor