Lombok簡介
Project Lombok makes java a spicier language by adding ‘handlers’ that know >how to build and compile simple, boilerplate-free, not-quite-java code.
github上官方是這麼描述lombok的:
lombok專案通過增加處理程式使我們的java語言更加刺激(簡潔和快速)。
先看個簡單示例:
我們做java開發的時候,最不少寫的就是javabean了,bean欄位都需要新增gettter/setter方法,往往我們只能一次又一次的使用ide生成gettter,setter
構造器等等。
lombok是如何幫我們解決這種重複性勞動呢?
-
package com.lhy.boot.lombok;
-
-
import lombok.Getter;
-
import lombok.Setter;
-
-
@Getter
-
@Setter
-
public class GetterSetterExample1 {
-
-
private int age = 10;
-
-
private String name ="張三丰";
-
-
private boolean registerd;
-
-
private String sex;
-
-
}
編譯後的class:
-
package com.lhy.boot.lombok;
-
-
public class GetterSetterExample1
-
{
-
private int age = 10;
-
-
private String name = "張三丰";
-
private boolean registerd;
-
private String sex;
-
-
public int getAge()
-
{
-
return this.age;
-
}
-
-
public String getName() {
-
return this.name;
-
}
-
-
public boolean isRegisterd() {
-
return this.registerd;
-
}
-
-
public String getSex() {
-
return this.sex;
-
}
-
-
public GetterSetterExample1 setAge(int age) {
-
this.age = age;
-
return this;
-
}
-
-
public GetterSetterExample1 setName(String name) {
-
this.name = name;
-
return this;
-
}
-
-
public GetterSetterExample1 setRegisterd(boolean registerd) {
-
this.registerd = registerd;
-
return this;
-
}
-
-
public GetterSetterExample1 setSex(String sex) {
-
this.sex = sex;
-
return this;
-
}
-
}
通過gettter,setter註解lombok已經幫我們自動生成了getter,setter方法!
是不是很神奇呢?lombok是怎麼的做到的?這個後邊再講,先把lombok ide外掛環境搭起來
下載並引用
-
<dependency>
-
<groupId>org.projectlombok</groupId>
-
<artifactId>lombok</artifactId>
-
<version>1.16.16</version>
-
</dependency>
或者到官網下載jar包 https://projectlombok.org/download
安裝ide外掛
myeclipse/eclipse
下載完成後 命令列執行
-
java -jar lombok-1.16.16.jar
彈出安裝介面:
specify location 選擇myeclipse安裝目錄,eclipse同理。
點選 install/update 安裝完成。
或者將jar包放入myeclipse 根目錄下
myeclipse.ini檔案末尾新增:
-
-javaagent:lombok-1.16.16.jar
重啟myeclipse即可。
安裝完畢後
開啟myeclipse about 可以看到
證明外掛安裝完成
IntelliJ IDEA
-
定位到 File > Settings > Plugins
-
點選 Browse repositories…
-
搜尋 Lombok Plugin
-
點選 Install plugin
-
重啟 IDEA
Lombok註解詳解
全域性配置檔案
我們可以從專案根目錄下新建一個lombok.config(當然目錄不是固定的,lombok會搜尋所有lombok.config檔案)
在這個檔案加入一行
config.stopBubbling = true
表示該檔案目錄為根目錄,lombok將從該目錄下開始搜尋。
每個子目錄都可以配置lombok.config 作用範圍只在該目錄下,並且覆蓋父目錄的配置。
Lombok通常為所有生成的節點生成註釋,新增@javax.annotation.Generated 。
可以用:
lombok.addJavaxGeneratedAnnotation = false 設定取消
下面看下lombok提供了哪些有趣的註解。
1.@val @var
使用Lombok ,java也能夠像javascript一樣使用弱型別定義變數了
val註解變數申明是final型別 var註解變數是非final型別
-
import java.util.ArrayList;
-
import java.util.HashMap;
-
import lombok.val;
-
-
public class ValExample {
-
public String example() {
-
val example = new ArrayList<String>();
-
example.add("Hello, World!");
-
val foo = example.get(0);
-
return foo.toLowerCase();
-
}
-
-
public void example2() {
-
val map = new HashMap<Integer, String>();
-
map.put(0, "zero");
-
map.put(5, "five");
-
for (val entry : map.entrySet()) {
-
System.out.printf("%d: %s\n", entry.getKey(), entry.getValue());
-
}
-
}
-
}
翻譯後
-
<span style="font-weight:normal;">import java.util.ArrayList;
-
import java.util.HashMap;
-
import java.util.Map;
-
-
public class ValExample {
-
public String example() {
-
final ArrayList<String> example = new ArrayList<String>();
-
example.add("Hello, World!");
-
final String foo = example.get(0);
-
return foo.toLowerCase();
-
}
-
-
public void example2() {
-
final HashMap<Integer, String> map = new HashMap<Integer, String>();
-
map.put(0, "zero");
-
map.put(5, "five");
-
for (final Map.Entry<Integer, String> entry : map.entrySet()) {
-
System.out.printf("%d: %s\n", entry.getKey(), entry.getValue());
-
}
-
}
-
}</span>
2.@NonNull
在方法或建構函式的引數上使用@NonNull,lombok將生成一個空值檢查語句。
-
<span style="font-weight:normal;"> import lombok.NonNull;
-
-
public class NonNullExample extends Something {
-
private String name;
-
-
public NonNullExample(@NonNull Person person) {
-
super("Hello");
-
this.name = person.getName();
-
}
-
}</span>
翻譯後
-
<span style="font-weight:normal;">import lombok.NonNull;
-
-
public class NonNullExample extends Something {
-
private String name;
-
-
public NonNullExample(@NonNull Person person) {
-
super("Hello");
-
if (person == null) {
-
throw new NullPointerException("person");
-
}
-
this.name = person.getName();
-
}
-
}</span>
3.@Cleanup
使用該註解能夠自動釋放io資源
-
<span style="font-weight:normal;"> import lombok.Cleanup;
-
import java.io.*;
-
-
public class CleanupExample {
-
public static void main(String[] args) throws IOException {
-
@Cleanup InputStream in = new FileInputStream(args[0]);
-
@Cleanup OutputStream out = new FileOutputStream(args[1]);
-
byte[] b = new byte[10000];
-
while (true) {
-
int r = in.read(b);
-
if (r == -1) break;
-
out.write(b, 0, r);
-
}
-
}
-
}</span>
翻譯後
-
<span style="font-weight:normal;">import java.io.*;
-
-
public class CleanupExample {
-
public static void main(String[] args) throws IOException {
-
InputStream in = new FileInputStream(args[0]);
-
try {
-
OutputStream out = new FileOutputStream(args[1]);
-
try {
-
byte[] b = new byte[10000];
-
while (true) {
-
int r = in.read(b);
-
if (r == -1) break;
-
out.write(b, 0, r);
-
}
-
} finally {
-
if (out != null) {
-
out.close();
-
}
-
}
-
} finally {
-
if (in != null) {
-
in.close();
-
}
-
}
-
}
-
}</span>
當然從1.7開始jdk已經提供了try with resources的方式自動回收資源
-
static String readFirstLineFromFile(String path) throws IOException {
-
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
-
return br.readLine();
-
}
-
}
4.@Getter/@Setter
-
<span style="font-weight:normal;">import lombok.AccessLevel;
-
import lombok.Getter;
-
import lombok.Setter;
-
-
public class GetterSetterExample {
-
-
-
-
-
-
-
@Getter @Setter private int age = 10;
-
-
-
-
-
-
-
-
-
@Setter(AccessLevel.PROTECTED) private String name;
-
-
@Override public String toString() {
-
return String.format("%s (age: %d)", name, age);
-
}
-
}</span>
翻譯後
-
<span style="font-weight:normal;"> public class GetterSetterExample {
-
-
-
-
private int age = 10;
-
-
-
-
-
private String name;
-
-
@Override public String toString() {
-
return String.format("%s (age: %d)", name, age);
-
}
-
-
-
-
-
-
-
public int getAge() {
-
return age;
-
}
-
-
-
-
-
-
-
public void setAge(int age) {
-
this.age = age;
-
}
-
-
-
-
-
-
-
protected void setName(String name) {
-
this.name = name;
-
}
-
}</span>
擴充套件配置:
lombok.accessors.chain
= [
true
|
false
]
(default: false)如果設定為true,生成的setter將返回this(而不是void),通過這個配置我們可以像jquery一樣愉快的鏈式程式設計了。可以在類加增加一個@Accessors 註解 配置chain屬性,優先於全域性配置。
lombok.accessors.fluent
= [
true
|
false
]
(default: false)如果設定為true,生成的getter和setter將不會使用bean標準的get、is或set進行字首;相反,方法將使用與欄位相同的名稱(減去字首)。可以在類加增加一個@Accessors註解,配置fluent屬性,優先於全域性配置
lombok.accessors.prefix
+=
a field
prefix (default: empty list)
給getter/setter方法增加字首 例如配置 +=M 原有的 getFoo方法將變為getMFoo方法。 lombok.getter.noIsPrefix
=
[
true
|
false
]
(default: false)
如果設定為true,那麼boolean型欄位生成的getter將使用get字首而不是預設的is字首
5.@ToString
生成一個toString方法,log debug神器
預設的toString格式為:ClassName(fieldName= fieleValue ,fieldName1=fieleValue)
-
<span style="font-weight:normal;">import lombok.ToString;
-
-
@ToString(exclude="id")
-
public class ToStringExample {
-
private static final int STATIC_VAR = 10;
-
private String name;
-
private Shape shape = new Square(5, 10);
-
private String[] tags;
-
private int id;
-
-
public String getName() {
-
return this.getName();
-
}
-
-
@ToString(callSuper=true, includeFieldNames=true)
-
public static class Square extends Shape {
-
private final int width, height;
-
-
public Square(int width, int height) {
-
this.width = width;
-
this.height = height;
-
}
-
}
-
}</span>
翻譯後
-
import java.util.Arrays;
-
-
ublic class ToStringExample {
-
private static final int STATIC_VAR = 10;
-
private String name;
-
private Shape shape = new Square(5, 10);
-
private String[] tags;
-
private int id;
-
-
public String getName() {
-
return this.getName();
-
}
-
-
public static class Square extends Shape {
-
private final int width, height;
-
-
public Square(int width, int height) {
-
this.width = width;
-
this.height = height;
-
}
-
-
@Override public String toString() {
-
return "Square(super=" + super.toString() + ", width=" + this.width + ", height=" + this.height + ")";
-
}
-
}
-
-
@Override public String toString() {
-
return "ToStringExample(" + this.getName() + ", " + this.shape + ", " + Arrays.deepToString(this.tags) + ")";
-
}
擴充套件配置:
lombok.toString.includeFieldNames
=
[true
| false
]
(default: true)
通常,lombok以fieldName=fieldValue的形式為每個欄位生成一個toString響應的片段。如果設定為false,lombok將省略欄位的名稱,可以在該註解上配置屬性includeFieldNames來標示包含的欄位,這樣可以覆蓋預設配置。
lombok.toString.doNotUseGetters
=
[true
| false
]
(default: false)
如果設定為true,lombok將直接訪問欄位,而不是在生成tostring方法時使用getter(如果可用)。可以在該註解上配置屬性doNotUseGetters來標示不使用getter的欄位,這樣可以覆蓋預設配置。
6.@EqualsAndHashCode
給類增加equals和hashCode方法
-
import lombok.EqualsAndHashCode;
-
-
@EqualsAndHashCode(exclude={"id", "shape"})
-
public class EqualsAndHashCodeExample {
-
private transient int transientVar = 10;
-
private String name;
-
private double score;
-
private Shape shape = new Square(5, 10);
-
private String[] tags;
-
private int id;
-
-
public String getName() {
-
return this.name;
-
}
-
-
@EqualsAndHashCode(callSuper=true)
-
public static class Square extends Shape {
-
private final int width, height;
-
-
public Square(int width, int height) {
-
this.width = width;
-
this.height = height;
-
}
-
}
-
}
翻譯後
-
import java.util.Arrays;
-
-
ublic class EqualsAndHashCodeExample {
-
private transient int transientVar = 10;
-
private String name;
-
private double score;
-
private Shape shape = new Square(5, 10);
-
private String[] tags;
-
private int id;
-
-
public String getName() {
-
return this.name;
-
}
-
-
@Override public boolean equals(Object o) {
-
if (o == this) return true;
-
if (!(o instanceof EqualsAndHashCodeExample)) return false;
-
EqualsAndHashCodeExample other = (EqualsAndHashCodeExample) o;
-
if (!other.canEqual((Object)this)) return false;
-
if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
-
if (Double.compare(this.score, other.score) != 0) return false;
-
if (!Arrays.deepEquals(this.tags, other.tags)) return false;
-
return true;
-
}
-
-
@Override public int hashCode() {
-
final int PRIME = 59;
-
int result = 1;
-
final long temp1 = Double.doubleToLongBits(this.score);
-
result = (result*PRIME) + (this.name == null ? 43 : this.name.hashCode());
-
result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
-
result = (result*PRIME) + Arrays.deepHashCode(this.tags);
-
return result;
-
}
-
-
protected boolean canEqual(Object other) {
-
return other instanceof EqualsAndHashCodeExample;
-
}
-
-
public static class Square extends Shape {
-
private final int width, height;
-
-
public Square(int width, int height) {
-
this.width = width;
-
this.height = height;
-
}
-
-
@Override public boolean equals(Object o) {
-
if (o == this) return true;
-
if (!(o instanceof Square)) return false;
-
Square other = (Square) o;
-
if (!other.canEqual((Object)this)) return false;
-
if (!super.equals(o)) return false;
-
if (this.width != other.width) return false;
-
if (this.height != other.height) return false;
-
return true;
-
}
-
-
@Override public int hashCode() {
-
final int PRIME = 59;
-
int result = 1;
-
result = (result*PRIME) + super.hashCode();
-
result = (result*PRIME) + this.width;
-
result = (result*PRIME) + this.height;
-
return result;
-
}
-
-
protected boolean canEqual(Object other) {
-
return other instanceof Square;
-
}
-
}
擴充套件配置:
lombok.config增加:
lombok.equalsAndHashCode.doNotUseGetters
=
[true
| false
]
(default: false)如果設定為true,lombok將直接訪問欄位,而不是在生成equals和hashcode方法時使用getter(如果可用)。
可以在該註解上配置屬性donotusegetter來標示不使用getter的欄位,這樣可以覆蓋預設配置。
lombok.equalsAndHashCode.callSuper
=
[call
| skip
| warn
]
(default: warn)如果設定為call,lombok將生成對hashCode的超類實現的呼叫。如果設定為skip,則不會生成這樣的呼叫。預設行為warn類似於skip,並帶有附加警告。
7.@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor
給類增加無參構造器 指定引數的構造器 包含所有引數的構造器
-
import lombok.AccessLevel;
-
import lombok.RequiredArgsConstructor;
-
import lombok.AllArgsConstructor;
-
import lombok.NonNull;
-
-
@RequiredArgsConstructor(staticName = "of")
-
@AllArgsConstructor(access = AccessLevel.PROTECTED)
-
public class ConstructorExample<T> {
-
private int x, y;
-
@NonNull private T description;
-
-
@NoArgsConstructor
-
public static class NoArgsExample {
-
@NonNull private String field;
-
}
-
}
翻譯後
-
public class ConstructorExample<T> {
-
private int x, y;
-
@NonNull private T description;
-
-
private ConstructorExample(T description) {
-
if (description == null) throw new NullPointerException("description");
-
this.description = description;
-
}
-
-
public static <T> ConstructorExample<T> of(T description) {
-
return new ConstructorExample<T>(description);
-
}
-
-
@java.beans.ConstructorProperties({"x", "y", "description"})
-
protected ConstructorExample(int x, int y, T description) {
-
if (description == null) throw new NullPointerException("description");
-
this.x = x;
-
this.y = y;
-
this.description = description;
-
}
-
-
public static class NoArgsExample {
-
@NonNull private String field;
-
-
public NoArgsExample() {
-
}
-
}
-
}
擴充套件配置:
lombok.anyConstructor.suppressConstructorProperties
=
[true
| false
]
(default: false
)如果將其設定為true,那麼lombok將跳過新增一個@java.bean.ConstructorProperties生成的構造器。這在android和GWT開發中很有用,因為這些註釋通常不可用。
8.@Data
包含以下註解的集合
@ToString,@EqualsAndHashCode,所有欄位的 @Getter 所有非final欄位的@Setter ,@RequiredArgsConstructor
-
import lombok.AccessLevel;
-
import lombok.Setter;
-
import lombok.Data;
-
import lombok.ToString;
-
-
@Data public class DataExample {
-
private final String name;
-
@Setter(AccessLevel.PACKAGE) private int age;
-
private double score;
-
private String[] tags;
-
-
@ToString(includeFieldNames=true)
-
@Data(staticConstructor="of")
-
public static class Exercise<T> {
-
private final String name;
-
private final T value;
-
}
-
}
翻譯後
9.@Value
@value是@data的不可變物件 (不可變物件的用處和建立:https://my.oschina.net/jasonultimate/blog/166810)
所有欄位都是私有的,預設情況下是final的,並且不會生成setter。預設情況下,類本身也是final的,因為不可變性不能強制轉化為子類。與@data一樣,有用toString()、equals()和hashCode()方法也是生成的,每個欄位都有一個getter方法,並且一個覆蓋每個引數的構造器也會生成。
10.@Builder
建築者模式
是現在比較推崇的一種構建值物件的方式。
-
import lombok.Builder;
-
import lombok.Singular;
-
import java.util.Set;
-
-
@Builder
-
public class BuilderExample {
-
private String name;
-
private int age;
-
@Singular private Set<String> occupations;
-
}
翻譯後
-
import java.util.Set;
-
-
public class BuilderExample {
-
private String name;
-
private int age;
-
private Set<String> occupations;
-
-
BuilderExample(String name, int age, Set<String> occupations) {
-
this.name = name;
-
this.age = age;
-
this.occupations = occupations;
-
}
-
-
public static BuilderExampleBuilder builder() {
-
return new BuilderExampleBuilder();
-
}
-
-
public static class BuilderExampleBuilder {
-
private String name;
-
private int age;
-
private java.util.ArrayList<String> occupations;
-
-
BuilderExampleBuilder() {
-
}
-
-
public BuilderExampleBuilder name(String name) {
-
this.name = name;
-
return this;
-
}
-
-
public BuilderExampleBuilder age(int age) {
-
this.age = age;
-
return this;
-
}
-
-
public BuilderExampleBuilder occupation(String occupation) {
-
if (this.occupations == null) {
-
this.occupations = new java.util.ArrayList<String>();
-
}
-
-
this.occupations.add(occupation);
-
return this;
-
}
-
-
public BuilderExampleBuilder occupations(Collection<? extends String> occupations) {
-
if (this.occupations == null) {
-
this.occupations = new java.util.ArrayList<String>();
-
}
-
-
this.occupations.addAll(occupations);
-
return this;
-
}
-
-
public BuilderExampleBuilder clearOccupations() {
-
if (this.occupations != null) {
-
this.occupations.clear();
-
}
-
-
return this;
-
}
-
-
public BuilderExample build() {
-
-
-
Set<String> occupations = ...;
-
return new BuilderExample(name, age, occupations);
-
}
-
-
@java.lang.Override
-
public String toString() {
-
return "BuilderExample.BuilderExampleBuilder(name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")";
-
}
-
}
-
}
11.@SneakyThrows
把checked異常轉化為unchecked異常,好處是不用再往上層方法丟擲了,美其名曰暗埋異常
-
import lombok.SneakyThrows;
-
-
public class SneakyThrowsExample implements Runnable {
-
@SneakyThrows(UnsupportedEncodingException.class)
-
public String utf8ToString(byte[] bytes) {
-
return new String(bytes, "UTF-8");
-
}
-
-
@SneakyThrows
-
public void run() {
-
throw new Throwable();
-
}
-
}
翻譯後:
-
import lombok.Lombok;
-
-
public class SneakyThrowsExample implements Runnable {
-
public String utf8ToString(byte[] bytes) {
-
try {
-
return new String(bytes, "UTF-8");
-
} catch (UnsupportedEncodingException e) {
-
throw Lombok.sneakyThrow(e);
-
}
-
}
-
-
public void run() {
-
try {
-
throw new Throwable();
-
} catch (Throwable t) {
-
throw Lombok.sneakyThrow(t);
-
}
-
}
-
}
12.@Synchronized
類似於Synchronized 關鍵字 但是可以隱藏同步鎖
-
import lombok.Synchronized;
-
-
ublic class SynchronizedExample {
-
private final Object readLock = new Object();
-
-
@Synchronized
-
public static void hello() {
-
System.out.println("world");
-
}
-
-
@Synchronized
-
public int answerToLife() {
-
return 42;
-
}
-
-
@Synchronized("readLock")
-
public void foo() {
-
System.out.println("bar");
-
}
翻譯後
-
public class SynchronizedExample {
-
private static final Object $LOCK = new Object[0];
-
private final Object $lock = new Object[0];
-
private final Object readLock = new Object();
-
-
public static void hello() {
-
synchronized($LOCK) {
-
System.out.println("world");
-
}
-
}
-
-
public int answerToLife() {
-
synchronized($lock) {
-
return 42;
-
}
-
}
-
-
public void foo() {
-
synchronized(readLock) {
-
System.out.println("bar");
-
}
-
}
-
}
xianzjdk推薦使用Lock了,這個僅供參考
13.@Getter(lazy=true)
如果getter方法計算值需要大量CPU,或者值佔用大量記憶體,第一次呼叫這個getter,它將一次計算一個值,然後從那時開始快取它
-
import lombok.Getter;
-
-
public class GetterLazyExample {
-
@Getter(lazy=true) private final double[] cached = expensive();
-
-
private double[] expensive() {
-
double[] result = new double[1000000];
-
for (int i = 0; i < result.length; i++) {
-
result[i] = Math.asin(i);
-
}
-
return result;
-
}
-
}
翻譯後
-
public class GetterLazyExample {
-
private final java.util.concurrent.AtomicReference<java.lang.Object> cached = new java.util.concurrent.AtomicReference<java.lang.Object>();
-
-
public double[] getCached() {
-
java.lang.Object value = this.cached.get();
-
if (value == null) {
-
synchronized(this.cached) {
-
value = this.cached.get();
-
if (value == null) {
-
final double[] actualValue = expensive();
-
value = actualValue == null ? this.cached : actualValue;
-
this.cached.set(value);
-
}
-
}
-
}
-
return (double[])(value == this.cached ? null : value);
-
}
-
-
private double[] expensive() {
-
double[] result = new double[1000000];
-
for (int i = 0; i < result.length; i++) {
-
result[i] = Math.asin(i);
-
}
-
return result;
-
}
14.@Log
可以生成各種log物件,方便多了
-
import lombok.extern.java.Log;
-
import lombok.extern.slf4j.Slf4j;
-
-
@Log
-
public class LogExample {
-
-
public static void main(String... args) {
-
log.error("Something's wrong here");
-
}
-
}
-
-
@Slf4j
-
public class LogExampleOther {
-
-
public static void main(String... args) {
-
log.error("Something else is wrong here");
-
}
-
}
-
-
@CommonsLog(topic="CounterLog")
-
public class LogExampleCategory {
-
-
public static void main(String... args) {
-
log.error("Calling the 'CounterLog' with a message");
-
}
-
}
翻譯為
-
public class LogExample {
-
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
-
-
public static void main(String... args) {
-
log.error("Something's wrong here");
-
}
-
}
-
-
public class LogExampleOther {
-
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleOther.class);
-
-
public static void main(String... args) {
-
log.error("Something else is wrong here");
-
}
-
}
-
-
public class LogExampleCategory {
-
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("CounterLog");
-
-
public static void main(String... args) {
-
log.error("Calling the 'CounterLog' with a message");
-
}
-
}
所有支援的log型別:
@CommonsLog
Createsprivate static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
@JBossLog
Createsprivate static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);
@Log
Createsprivate static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
@Log4j
Createsprivate static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);
@Log4j2
Createsprivate static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
@Slf4j
Creates private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
@XSlf4j
Createsprivate static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
擴充套件配置:
lombok.log.fieldName
= an
identifier (default: log
).生成log欄位的名稱
預設為log lombok.log.fieldIsStatic
=
[true
| false
]
(default: true)生成log是否是static的 預設為static
官方文件說明:https://projectlombok.org/features/all
Lombok原理
lombok通過簡單的註解標誌就能夠實現複雜的程式碼生成,他是怎麼做到的?
lombok註解不是我們常見的runtime註解,而是source註解或者class註解,
在沒有jsr之前我們可以通過反射在執行是獲取註解值,但是這樣效率很低,而且沒辦法做到編譯檢查,對開發人員一些不合的編碼錯誤給出警告,
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增加新的節點(程式碼塊)
ide中使用Lombok的注意事項
1.專案中要使用lombok 不僅ide要支援(否則一堆錯誤),專案中也要引入jar包
2.如果配置lombok.config檔案,修改檔案的屬性值後,並不會自動重新編譯class檔案,ide編輯器也不會自動更新,所有每次修改配置檔案後最後關閉java檔案視窗重新開啟,並且clean下專案