lombok详解
简介
一个java库,基于注解处理器,在编译时,处理指定的注解,生成一个java bean的getter、setter等方法。它可以减少样板代码的编写,简化java开发。
lombok是在编译时生成java代码,运行时不需要依赖lombok。
lombok的优缺点:
- 优点:快速生成getter、setter等方法,加快开发速度
- 缺点:lombok的侵入性比较强,使用lombok时IDE必须安装插件。
入门案例
第一步:在项目中添加lombok的依赖
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope> <!--lombok是编译时依赖,运行时不需要-->
</dependency>
第二步:如果是基于idea开发,在idea中安装lombok插件。下载插件:File - settings - Plugins,搜索lombok,点击安装即可
第三步:使用lombok来生成getter、setter方法
@Data
public class Student {private Integer id;private String name;
}
完成。
查看生成的代码:
public class Student {private Integer id;private String name;public Student() {}public Integer getId() {return this.id;}public String getName() {return this.name;}public void setId(Integer id) {this.id = id;}public void setName(String name) {this.name = name;}public boolean equals(Object o) {if (o == this) {return true;} else if (!(o instanceof Student)) {return false;} else {Student other = (Student)o;if (!other.canEqual(this)) {return false;} else {Object this$id = this.getId();Object other$id = other.getId();if (this$id == null) {if (other$id != null) {return false;}} else if (!this$id.equals(other$id)) {return false;}Object this$name = this.getName();Object other$name = other.getName();if (this$name == null) {if (other$name != null) {return false;}} else if (!this$name.equals(other$name)) {return false;}return true;}}}protected boolean canEqual(Object other) {return other instanceof Student;}public int hashCode() {int PRIME = true;int result = 1;Object $id = this.getId();result = result * 59 + ($id == null ? 43 : $id.hashCode());Object $name = this.getName();result = result * 59 + ($name == null ? 43 : $name.hashCode());return result;}public String toString() {return "Student(id=" + this.getId() + ", name=" + this.getName() + ")";}
}
总结:在java bean上添加@Data注解,生成了getter、setter、equals、hashcode、toString方法
基本使用
lombok只会处理成员变量,不会处理静态变量。
常用注解
标注在类上的注解:
- @Data:注解在类上,为所有的成员变量生成getter、setter方法、equals方法、hashCode方法、toString方法。相当于@Getter、@Setter、@RequiredArgsConstructor、@ToString、@EqualsAndHashCode。要注意的是,如果成员变量被final修饰,只会生成它的getter方法,并且会生成一个包含该变量的构造方法。
- @NoArgsConstructor:生成无参的构造方法。
- @AllArgsConstructor:生成包含类中所有字段的构造方法。
- @RequiredArgsConstructor:为所有被final修饰的成员变量生成构造方法
- @EqualsAndHashCode:生成hashCode和equals方法。
- @ToString:添加toString方法。
- @Builder:使用建造者模式来创建类的实例
- @Slf4j:生成log常量,
private static final Logger log = LoggerFactory.getLogger(UserController.class);
,需要额外依赖slf4j
标注在类或字段上:
- @Setter:标注在类或字段上,标注在类上时为所有字段生成setter方法,标注在字段上时只为该字段生成setter方法。
- @Getter:使用方法同上,区别在于生成的是getter方法。
注意事项:
- 如果一个类继承了某个类,并且这个类被@Data注解标注,那么最好再加一个注解@EqualsAndHashCode(callSuper = true),表示生成的equals、hashcode方法会调用父类属性。
@Data
@EqualsAndHashCode(callSuper = true)
public class Student extends Human {private Integer id;private String name;
}
内部机制
lombok的核心机制,主要在于编译时解析注解。
对于注解的解析,在jdk5引入了注解之后,也提供了两种注解的处理方式:
- 运行时解析:依赖反射,注解的生命周期必须为运行时
- 编译时解析:
- apt:注解处理工具,Annotation Processing Tool,jdk1.5引入,1.7标记为已过期,因为它的api都在com.sun.mirror非标准包下,而且没有集成到javac中,需要额外运行
- 插件式注解处理器:Pluggable Annotation Processing API,jdk1.6加入,作为apt的替代方式,编译器在执行时会调用注解处理器。
lombok的内部正是基于插件式注解处理器。插件式注解处理器相当于是编译器对外提供的接口,lombok是该接口的实现类,
lombok的执行机制:
- 编译器对源代码进行分析,生成了一棵抽象语法树(AST)
- 运行过程中调用注解处理器,这里是调用lombok,还可以有其他
- lombok处理抽象语法树,找到它需要处理的注解,修改语法树,增加getter和setter方法定义的相应树节点
- 编译器使用修改后的抽象语法树生成字节码文件
所以lombok是编译时依赖,运行时不需要依赖lombok
法树(AST)
- 运行过程中调用注解处理器,这里是调用lombok,还可以有其他
- lombok处理抽象语法树,找到它需要处理的注解,修改语法树,增加getter和setter方法定义的相应树节点
- 编译器使用修改后的抽象语法树生成字节码文件
所以lombok是编译时依赖,运行时不需要依赖lombok