JAVA

Lombok介绍及使用方法

1. lombok简介

在写Java程序的时候经常会遇到如下情形:新建了一个Class类,然后在其中设置了几个字段,最后还需要花费很多时间来建立getter,setter方法还有构造函数等 。lombok项目的产生就是为了省去我们手动创建getter和setter方法的麻烦,它能够在我们编译源码的时候自动帮我们生成getter和setter方法。即它最终能够达到的效果是:在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法

2. 安装
  • 2.1 Maven添加依赖,lombok也就是一个普通的jar包
<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.14</version>
            <scope>provided</scope>
        </dependency><em></em>
  • 2.2 eclipse安装
  • 1.从官网下载lombok.jar(https://projectlombok.org/download-edge), 下载到mac的目录上。
  • CD到lombok.jar下载目录,终端下运行java -jar lombok.jar命令
  • 点击Specify location,弹出的对话框,选择Eclipse.ini文件。
  • 3.点击Install/Update
  • 4.重启eclipse,lombok即可生效
  • 5.打开eclipse.ini可以看到最下面追加一行配置(-javaagent:/Applications/SpringToolSuite4.app/Contents/Eclipse/lombok.jar)
-startup
../Eclipse/plugins/org.eclipse.equinox.launcher_1.6.300.v20210813-1054.jar
--launcher.library
../Eclipse/plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.2.300.v20210828-0802
-product
org.springframework.boot.ide.branding.sts4
--launcher.defaultAction
openFile
-vm
../Eclipse/plugins/org.eclipse.justj.openjdk.hotspot.jre.full.macosx.x86_64_17.0.0.v20211012-1059/jre/lib/libjli.dylib
-vmargs
-Dosgi.requiredJavaVersion=11
-Dosgi.dataAreaRequiresExplicitInit=true
-Xms256m
-Xmx2048m
--illegal-access=permit
--add-modules=ALL-SYSTEM
-XstartOnFirstThread
-Dorg.eclipse.swt.internal.carbon.smallFonts
-Xdock:icon=../Resources/sts4.icns
-javaagent:/Applications/SpringToolSuite4.app/Contents/Eclipse/lombok.jar
3. lombok使用
  • 3.1 @NonNull: 可以帮助我们避免空指针。
package io.fredia.femicro.gate.ratelimit.config;

import io.micrometer.core.lang.NonNull;

/**
 * LombokDemo
 * 
 * @author : Fredia
 * @since : 2018年4月11日
 * @version : v1.0.0
 */
public class LombokDemoClass {

    public void NonNullDemo(@NonNull Object obj) {

    }
}
<em></em>
  • 3.2 @Cleanup: 自动帮我们调用close()方法。
package io.fredia.femicro.gate.ratelimit.config;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import lombok.Cleanup;

/**
 * LombokDemo
 * 
 * @author : Fredia
 * @since : 2018年4月11日
 * @version : v1.0.0
 */
public class LombokDemoClass {

    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);
        }
    }
}

我们都知道io操作完必须关闭,所以此注解帮我们完成了如下的操作。

  in.close();
  out.close();
  • 3.3 @Getter / @Setter: 自动生成Getter/Setter方法
package io.fredia.femicro.gate.ratelimit.config;

import java.util.Date;

import lombok.Getter;
import lombok.Setter;

/**
 * LombokDemo
 * 
 * @author : Fredia
 * @since : 2018年4月11日
 * @version : v1.0.0
 */
public class LombokDemo {

    @Getter
    @Setter
    private String key;
    @Getter
    @Setter
    private Date expiration;

}<em></em>
  • 3.4 @NoArgsConstructor: 自动生成无参数构造函数。
import lombok.NoArgsConstructor;

/**
 * LombokDemo
 * 
 * @author : Fredia
 * @since : 2018年4月11日
 * @version : v1.0.0
 */
@NoArgsConstructor
public class LombokDemo {

    private String key;
    private Long remaining;
    private Long reset;
    private Date expiration;

    public static void main(String[] args) {
            LombokDemo lom2 = new LombokDemo();
    }
}
  • 3.5 @AllArgsConstructor: 自动生成全参数构造函数。
import lombok.AllArgsConstructor;
/**
 * LombokDemo
 * 
 * @author : Fredia
 * @since : 2018年4月11日
 * @version : v1.0.0
 */
@AllArgsConstructor
public class LombokDemo {

    private String key;
    private Long remaining;
    private Long reset;
    private Date expiration;

    public static void main(String[] args) {
        LombokDemo lom = new LombokDemo(key, remaining, reset, expiration);
    }
}
  • 3.6 @Data: 自动为所有字段添加@ToString, @EqualsAndHashCode, @Getter方法,为非final字段添加@Setter,和@RequiredArgsConstructor@RequiredArgsConstructor
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * LombokDemo
 * 
 * @author : Fredia
 * @since : 2018年4月11日
 * @version : v1.0.0
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LombokDemo {

    private String key;
    private Long remaining;
    private Long reset;
    private Date expiration;

}
4. lombok实现原理分析

接下来进行lombok能够工作的原理分析,以Oracle的javac编译工具为例。
自从Java 6起,javac就支持“JSR 269 Pluggable Annotation Processing API”规范,只要程序实现了该API,就能在javac运行的时候得到调用。
举例来说,现在有一个实现了”JSR 269 API”的程序A,那么使用javac编译源码的时候具体流程如下:

javac对源代码进行分析,生成一棵**抽象语法树(AST) **
运行过程中调用实现了”JSR 269 API”的A程序
此时A程序就可以完成它自己的逻辑,包括修改第一步骤得到的抽象语法树(AST)
javac使用修改后的抽象语法树(AST)生成字节码文件

所以lombok本质上就是这样的一个实现了”JSR 269 API”的程序。在使用javac的过程中,结合官方说明,它编译的流程如下:

javac对源代码进行分析,生成一棵抽象语法树(AST)**
运行过程中调用实现了”JSR 269 API”的lombok程序
此时lombok就对第一步骤得到的AST进行处理,找到@Data注解所在类对应的语法树(AST),然后修改该语法树(AST),增加getter和setter方法定义的相应树节点
javac使用修改后的抽象语法树(AST)生成字节码文件

5. 总结
lombok的实现:就是元注解出现后注解运行生命周期里面的编译周期,这个就是 JSR 269 Pluggable Annotation Processing API,就是源代码在编译成字节码的时候修改了语法树的节点规则进行了加强生成,
以后可以更加快捷的敲代码了。