lombok使用

Lombok使用

[TOC]

介绍

lombok可用用来简化我们的代码。

比如,通过在Pojo上添加lombok提供的@Data注解,我们就不用再手动写get set方法了。

1
2
3
4
5
6
7
8
9
10
11
import lombok.Data;

@Data
public class Student {
private String name;

public static void main(String[] args) {
new Student().getName();
}
}

同理,也可以通过其他注解来省去构造、toString、equels、stream自动关闭、判断是否为Null值等等。

配置

maven配置

添加lombok依赖

1
2
3
4
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

添加lombok插件(非必须)

1
2
3
4
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
</plugin>

通过插件,我们可以进一步规定lombok的一些细节配置。比如,我们可以通过配置delombok来反编译生成不带有lombok注解的源码.

delombok
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<configuration>
<!-- 默认源路径会是${project.basedir}/src/main/lombok,所以需要我们自己指定实际需要反编译的类路径 -->
<sourceDirectory>
${project.basedir}/src/main/com/focustech/naja/lombok/sample
</sourceDirectory>
<!-- 默认输出路径会${project.build.directory}/generated-sources/delombok,我们也可以自己指定输出路径 -->
<outputDirectory>${project.build.directory}/generated-sources/diy/path</outputDirectory>
<encoding>utf-8</encoding>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
</execution>
</executions>
</plugin>

lombok-maven-plugin提供的其他额外功能具体见:

http://anthonywhitford.com/lombok.maven/lombok-maven-plugin/index.html

IntelliJ配置

IntelliJ Lombok插件

插件市场搜索lombok并添加。

Settings

Settings > Build,Execution,Deployment > Compiler > Annotation Processors

打开Enable annotation processing。

注解使用

val

val是lombok提供的一种类型,位于lombok.val。注解类型。

1
public @interface val {}

可以使用val来声明局部变量,而不用指定变量的具体类型,感觉有点类似于JS中的var,let。

注意!被声明为val的变量会成为final变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Test
public void testVal_01() {
val score = new Score(100);
val student = new Student("A", score);
logger.info("student info : {}", student);
student.toString();
}

@Test
public void testVal_02() {
val map = new HashMap<Student, Teacher>() {{
put(new Student("A", new Score(60)), new Teacher("Mr.Wang"));
put(new Student("B", new Score(100)), new Teacher("Mr.Liu"));
}};
for (val entry : map.entrySet()) {
logger.info("teacher {} has a student {}", entry.getValue().getName(), entry.getKey().getName());
}
}

@Test
public void testVal_03(){
val a = 1 + 1;
// a = 3; 无法这样做,因为val修饰的变量会修饰为final
}

配置支持

lombok.val.flagUsage = [warning | error] (default: not set)

配置为warn或者error时,对于项目中使用了val注解的,会给出warn提示或者error直接中断编译。

var

与val类似,都是用来声明局部变量,但区别在于,var不会将变量标记为final。

配置支持

lombok.var.flagUsage = [warning | error] (default: not set)

配置为warn或者error时,对于项目中使用了var注解的,会给出warn提示或者error直接中断编译。

@NonNull

用于标记方法参数,如果该参数为null,则会抛出异常。缺点是不能自定义错误信息内容。

1
2
3
private void print(@NonNull String s) {
System.out.println("content = " + s);
}

配置支持

lombok.nonNull.exceptionType = [NullPointerException | IllegalArgumentException | JDK | Guava | Assertion] (default: NullPointerException).

可以指定出现null时抛出哪种异常,或者是根据指定策略生成Assert风格代码。

@Getter/@Setter

可应用在类级别与成员变量级别,为成员变量生成get,set方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Getter
public class Food {

private String name;
/**
* 可以定义方法访问级别
*/
private @Setter(AccessLevel.PACKAGE)
double price;

/**
* 对静态变量并不会生效
*/
public static int type;

}

配置支持

lombok.accessors.chain = [true | false] (default: false)

如果配置为true,那么set方法将不是返回void,而是返回this。或者也可以使用@Accessors注解。注:@Accessors注解优先级比该配置高。

lombok.accessors.fluent = [true | false] (default: false)

如果配置为true,那么get set方法名将不是标准的getXxx,setXxx,而是与成员变量相同。

lombok.accessors.prefix += a field prefix (default: empty list)

打个比方,如果一个类的成员变量叫myName,然后配置lombok.accessors.prefix += my,那么生成的getter和setter都会自动去除my前缀,成为getName()setName()

lombok.getter.noIsPrefix = [true | false] (default: false)

当为true时,boolean类型的成员生成的getter将不会是is开头,而是get开头。

lombok.setter.flagUsage = [warning | error] (default: not set)

检测项目是否用了setter注解,给出warning或者直接error终止编译。

lombok.getter.flagUsage = [warning | error] (default: not set)

检测项目是否用了getter注解,给出warning或者直接error终止编译。

lombok.copyableAnnotations = [A list of fully qualified types] (default: empty list)

@ToString

用于生成toString方法。

如果需要指定某个字段不被toString输出,可以加上@ToString.Exclude标记。

可以在类上添加@ToString(onlyExplicitlyIncluded=true)来实现只输出被@ToString.Include标记的字段。

如果需要定义字段在toString中的出现顺序,可以使用@ToString.Include(rank=x)定义rank来实现。

定义@ToString(callSupper=true)可以额外调用父类的toString。

一般来说,toString会调用字段的getter方法。但可以通过配置来使其直接输出字段的toString,只需加上@ToString(doNotUseGetters=true)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@ToString(callSuper = true)
@Data
public class Father extends FamilyMember{
private String name;

private int age;

private List<String> scheduleList;

// toString将不输出father的兴趣爱好
@ToString.Exclude
private List<String> hobbies;
}

@Data
@ToString(onlyExplicitlyIncluded = true)
public class Son {

@ToString.Include
private String name;

private int age;

@ToString.Include(rank = 10)
private int grade;

}

配置支持

lombok.toString.includeFieldNames = [true | false] (default: true)

lombok.toString.doNotUseGetters = [true | false] (default: false)

lombok.toString.callSuper = [call | skip | warn] (default: skip)

lombok.toString.flagUsage = [warning | error] (default: not set)

各功能点见名之意,上面已经描述过了,不再赘述。

@Log

很好用的一个功能,通常我们记录日志的时候,都需要手动创建一个log静态成员。这个注解可以直接帮我们生成这个成员,不需要再手写了。

比如,使用对应slf4j的注解@Slf4j,则会自动生成:

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);

不同的Log框架对应不同的Log注解:

日志框架 全限定名 对应Lombok @Log注解
Apache Common Log org.apache.commons.logging.Log @CommonsLog
Flogger com.google.common.flogger.FluentLogger @Flogger
JBoss Log org.jboss.logging.Logger @JBossLog
Java Log java.util.logging.Logger @Log
Log4j org.apache.log4j.Logger @Log4j
Log4j2 org.apache.logging.log4j.Logger @Log4j2
Slf4j org.slf4j.Logger @Slf4j
XSlf4j org.slf4j.ext.XLogger @XSlf4j
CustomLog com.foo.your.Logger @CustomLog

定义日志的logger name

通常我们自己写日志的话,可能会通过getLogger("FACC_LOG"),来指定具体的logger,这里的”FACC_LOG“在lombok里叫做topic,我们可以通过@Slf4j(topic=”FACC_LOG”)来达成一样的效果。

自定义Log注解

可以通过Lombok.config来自定义我们自己的日志注解。

1
lombok.log.custom.declaration = com.foo.your.Logger com.foo.your.LoggerFactory.createYourLog(TYPE)(TOPIC)

第一部分

lombok.log.custom.declaration = com.foo.your.Logger定义Logger类全限定名。

第二部分

在第一部分后跟一个空格,后见加上Logger的工厂类与工厂方法。com.foo.your.LoggerFactory.createYourLog

第三部分

是放在括号中的一个参数,可以是:TYPENAMETOPIC。topic可以不配置。也可以和type/name搭配。type/name二选一。

如果是TYPE,那么生成的getLogger入参则是当前所在的Class类类型。如果是NAME,则为当前Class类的全限定名。如果是TOPIC,那么@Custom(topic=”xxx”)定义的topic内容将被传入getLogger(String xxx)

指定生成的log成员变量名

lombok.log.fieldName = log,配置在lombok.config中,默认是log,我们可以定义成别的,比如logger之类的。

限制项目使用的Log类型

为了防止各种各样的@Log注解出现在项目中,可以通过lombok.config来关闭其他注解,阻止其他注解通过编译。

所有配置见下方:

lombok.log.apacheCommons.flagUsage = [warning | error] (default: not set)

lombok.log.custom.flagUsage = [warning | error] (default: not set)

lombok.log.flagUsage = [warning | error] (default: not set)

lombok.log.flogger.flagUsage = [warning | error] (default: not set)

lombok.log.javaUtilLogging.flagUsage = [warning | error] (default: not set)

lombok.log.jbosslog.flagUsage = [warning | error] (default: not set)

lombok.log.log4j.flagUsage = [warning | error] (default: not set)

lombok.log.log4j2.flagUsage = [warning | error] (default: not set)

lombok.log.slf4j.flagUsage = [warning | error] (default: not set)

lombok.log.xslf4j.flagUsage = [warning | error] (default: not set)

@Data

该注解是对@ToString、@EqualsAndHashCode、@Getter/@Setter 和@RequiredArgsConstructor的集成。配了一个@Data,也就配置了这几个注解。

如果需要精细化配置的化,再特殊指定其他的几个注解。

@EqualsAndHashCode

用于生成equals方法以及重写hashCode。

总结

比较常用的就是@Data,@Getter,@Setter,@Log系列。这几个重点了解下就行了,其他的一般也不太推荐使用。