Lombok实战
Lombok是一个可以通过注解来帮助我们简化消除一些必须有但显得很臃肿的Java代码的一种工具,通过使用对应的注解,可以在编译源码的时候动态添加源码。
简介
Lombok是一款Java开发插件,使得Java开发者可以通过其定义的一系列注解来消除业务工程中冗长和繁琐的代码,尤其对于简单的Java模型对象(POJO)。 在开发环境中使用Lombok插件后,Java开发人员可以节省出重复构建,诸如HashCode和Equals这样的方法以及各种业务对象模型的accessor和ToString等方法的大量时间。 对于这些方法,它能够在编译源代码期间自动帮我们生成这些方法,且并不会如反射那样降低程序的性能。
使用方法
使用lombok项目的方法很简单,分为四个步骤:
- 安装插件,在编译类路径中加入lombok.jar包(具体安装方法可自己百度);
- 在需要简化的类或方法上,加上要使用的注解;
- 使用支持lombok的编译工具编译源代码(关于支持lombok的编译工具,见4.支持lombok的编译工具);
- 编译得到的字节码文件中自动生成Lombok注解对应的方法或代码;
Lombok使用
引入lombok依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
@Getter/@Setter
为字段生成Getter和Setter方法,可以注解到字段或者类上(注解在类上会为类中的所有字段生成Getter和Setter方法),默认是public类型的,如果需要的话可以修改方法的访问级别。
@NoArgsConstructor
生成一个无参构造方法。当类中有final字段没有被初始化时,编译器会报错,此时可用@NoArgsConstructor(force = true),然后就会为没有初始化的final字段设置默认值 0 / false / null, 这样编译器就不会报错。对于具有约束的字段(例如@NonNull字段),不会生成检查或分配,因此请注意,正确初始化这些字段之前,这些约束无效。
@NonNull
@RequiredArgsConstructor
生成构造方法(可能带参数也可能不带参数),如果带参数,这参数只能是以final修饰的未经初始化的字段,或者是以@NonNull注解的未经初始化的字段。 @RequiredArgsConstructor(staticName = “of”)会生成一个of()的静态方法,并把构造方法设置为私有的
@AllArgsConstructor
@ToString
生成toString()方法,默认情况下它会按顺序(以逗号分隔)打印你的类名称以及每个字段。可以这样设置不包含哪些字段,可以指定一个也可以指定多个@ToString(exclude = “id”) / @ToString(exclude = {“id”,“name”})
如果继承的有父类的话,可以设置callSuper 让其调用父类的toString()方法,例如:@ToString(callSuper = true)
@EqualsAndHashCode
生成hashCode()和equals()方法,默认情况下,它将使用所有非静态,非transient字段。但可以通过在可选的exclude参数中来排除更多字段。或者,通过在of参数中命名它们来准确指定希望使用哪些字段。 // exclude 排除字段 @EqualsAndHashCode(exclude = {“password”, “salt”}) // of 指定要包含的字段 @EqualsAndHashCode(of = {“id”, “phone”, “password”})
@Data
@Data 包含了 @ToString、@EqualsAndHashCode、@Getter / @Setter和@RequiredArgsConstructor的功能
@Value
@Value 将字段都变成不可变类型:使用final修饰, 同时还包含@ToString、@EqualsAndHashCode、@AllArgsConstructor 、@Getter(注意只有Getter没有Setter)
@Log
生成log对象,用于记录日志,可以通过topic属性来设置getLogger(String name)方法的参数 例如 @Log4j(topic = “com.xxx.entity.User”),默认是类的全限定名,即 类名.class,log支持以下几种:
- @Log java.util.logging.Logger
- @Log4j org.apache.log4j.Logger
- @Log4j2 org.apache.logging.log4j.Logger
- @Slf4j org.slf4j.Logger
- @XSlf4j org.slf4j.ext.XLogger
- @CommonsLog org.apache.commons.logging.Log
- @JBossLog org.jboss.logging.Logger
@SneakyThrows
@Synchronized
@Cleanup
主要用来修饰 IO 流相关类, 会在 finally 代码块中对该资源进行 close();
@Getter(lazy = true)
标注字段为懒加载字段,懒加载字段在创建对象时不会进行初始化,而是在第一次访问的时候才会初始化,后面再次访问也不会重复初始化
@Wither
提供了给final字段赋值的一种方法
@Builder
@Builder注释为你的类生成复杂的构建器API。
@Delegate
为List类型的字段生成一大堆常用的方法,其实这些方法都是List中的方法
注意:一个类中只能使用一个@Delegate注解,因为使用多个会生成多个size()方法,从而会编译报错。
原理分析
接下来,我们进行lombok的原理分析,以Oracle的javac编译工具为例。自Java 6起,javac开始支持JSR 269 Pluggable Annotation Processing API规范,只要程序实现了该API,就能在java源码编译时调用定义的注解。举例来说,现在有一个实现了”JSR 269 API”的程序A,那么使用javac编译源码的时候具体流程如下:
- javac对源代码进行分析,生成一棵抽象语法树(AST);
- 运行过程中调用实现了”JSR 269 API”的A程序;
- 此时A程序就可以完成它自己的逻辑,包括修改第一步骤得到的抽象语法树(AST);
- javac使用修改后的抽象语法树(AST)生成字节码文件;
参考资料
Lombok的官方地址:https://projectlombok.org/ Lombok的Github地址:https://github.com/rzwitserloot/lombok