Java 开发工具–Lombok介绍
2017-10-13 00:15
381 查看
Java 开发工具–Lombok介绍
问题描述
在写POJO代码时,经常需要生成getter和setter方法,以及hashcode、tostring和equals等代码。感觉甚是麻烦,虽然有Eclipse或者intellij IDEA快捷键帮我们自动生成些代码,但感觉还是麻烦(其实就是懒)。偶然中,得知Lombok Project,通过使用注解,可以消除冗余的java代码。
官网的介绍:Project Lombok makes java a spicier language by adding ‘handlers’ that know >how to build and compile simple, boilerplate-free, not-quite-java code.
如何使用
如果是maven管理的项目,通过引入dependency即可:<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.12</version> <scope>provided</scope> </dependency>
Gradle项目的引入方式类似:
provided group: 'org.projectlombok', name: 'lombok', version: '1.16.18'
另外,在spring boot项目中,引入Lombok时没有必要指定和,因为 spring boot 已经帮我们自动配置好。
如何安装
先说IDEA,在IDEA中安装Lombok需要先安装插件,快捷键 Ctrl + Alt + S,然后选择 plugins——> browse repositories,搜索 Lombok,install即可,安装需要重启。其次,Lombok是在编译时期,自动生成所需方法的,所以需要开启annotation processing;依旧是刚才的快捷键,可以搜索”annotation processing”,然后选择”Enable annotation processing”.
如果是Eclipse的话,官网下载最新的Lombok.jar,双击或者
`java -jar lombok.jar在弹出的窗口,确认刚才 Lombok 扫描整个硬盘得到的Eclipse安装程序结果即可(Eclipse,MyEclipse,STS(Spring tool suite)),点击 Install/Update。
注解
刚才提到,Lombok是通过注解来减少编码的,那都提供哪些注解呢?不完全统计:
@NonNull:标识对象是否为空,为空则抛出异常 @Getter/@Setter:自动生成Getter/Setter方法 @ToString:覆盖tostring方法,可以添加限制条件 @EqualsAndHashCode:覆盖equal和hashCode方法,生成方法时只会使用类中的非静态和非transient成员变量 @Data:@Getter/@Setter, @ToString, @EqualAndHashCode,@AllArgsConstructor等组合 @Cleanup:用在变量前面,可以保证此变量代表的资源会被自动关闭,默认是调用资源的close()方法,如果该资源有其它关闭方法,可使用@Cleanup(“methodName”)来指定要调用的方法 @NoArgsConstructor/@RequiredArgsConstructor /@AllArgsConstructor:第二个注解使用类中所有带有@NonNull注解的或带有final修饰的非静态成员变量生成对应的构造方法, @Log:类注解,可以省去从日志工厂生成日志对象这一步,直接进行日志记录,具体注解根据日志工具的不同而不同,同时,可以在注解中使用topic来指定生成log对象时的类名 @Builder:关于build模式,可以参考《Effective java》这本书 @Value @SneakyThrows @Synchronized
实例代码判断
上面的注解简介太模糊?看看实例:1 @Getter & @Setter & @ToString
public class Person { private boolean employed; private String name; Person() { } public String say() { return this.getName(); } public String toString() { return "Person(employed=" + this.isEmployed() + ", name=" + this.getName() + ")"; } public boolean isEmployed() { return this.employed; } public void setEmployed(boolean employed) { this.employed = employed; } public String getName() { return this.name; } protected void setName(String name) { this.name = name; } }
如果使用Lombok提供的注解:
@ToString class Person { @Getter @Setter private boolean employed; @Getter @Setter(AccessLevel.PROTECTED) private String name; public String say() { return getName(); } }
2. @Builder
这次先看看使用注解之前的java code:@Builder public class BuilderExample { private String name; private int age; }
再看看其经过编译之后的java code:
import java.beans.ConstructorProperties; public class BuilderExample { private String name; private int age; @ConstructorProperties({"name", "age"}) BuilderExample(String name, int age) { this.name = name; this.age = age; } public static BuilderExample.BuilderExampleBuilder builder() { return new BuilderExample.BuilderExampleBuilder(); } public static class BuilderExampleBuilder { private String name; private int age; BuilderExampleBuilder() { } public BuilderExample.BuilderExampleBuilder name(String name) { this.name = name; return this; } public BuilderExample.BuilderExampleBuilder age(int age) { this.age = age; return this; } public BuilderExample build() { return new BuilderExample(this.name, this.age); } public String toString() { return "BuilderExample.BuilderExampleBuilder(name=" + this.name + ", age=" + this.age + ")"; } } }
3. @Data
先看使用注解的类:@Data public class User { private Integer id; private String password; }
编译之后的类长这样:
public class User { private Integer id; private String password; public User() { } public Integer getId() { return this.id; } public String getPassword() { return this.password; } public void setId(Integer id) { this.id = id; } public void setPassword(String password) { this.password = password; } public boolean equals(Object o) { if (o == this) { return true; } else if (!(o instanceof User)) { return false; } else { User other = (User)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$password = this.getPassword(); Object other$password = other.getPassword(); if (this$password == null) { if (other$password != null) { return false; } } else if (!this$password.equals(other$password)) { return false; } return true; } } } protected boolean canEqual(Object other) { return other instanceof User; } public int hashCode() { int PRIME = true; int result = 1; Object $id = this.getId(); int result = result * 59 + ($id == null ? 43 : $id.hashCode()); Object $password = this.getPassword(); result = result * 59 + ($password == null ? 43 : $password.hashCode()); return result; } public String toString() { return "User(id=" + this.getId() + ", password=" + this.getPassword() + ")"; } }
更多注解的用法,感兴趣的话,请参考官网。
Lombok原理
采用JSR269所提出的插入式注解处理(Pluggable Annotation Processing),并结合动态代码生成技术所开发的。如下图所示:图示为 javac 的编译过程,java文件首先通过进行解析构建出一个AST,然后执行注解处理,最后经过分析优化生成二进制的.class文件。
Annotation Processing 是在解析和生成之间的一个步骤。
上图是 Lombok 处理流程,在Javac 解析成抽象语法树之后(AST),Lombok 根据自己的注解处理器,动态的修改 AST,增加新的节点(所谓代码),最终通过分析和生成字节码。
Lombok缺点
这么好的工具,那可以应用到生产环境吗?真不一定,Lombok 注解的引入一定程度上会造成源码的可读性(不是所有人都了解其使用)和完整性,而且生成环境使用,不一定还会遇到什么坑,看看其代码托管GitHub的issue就知道。不过反过来一想,issue 开得多,不正说明其应用还是很广泛的?
参考
基本实现原理jdk-compilation-overview
相关文章推荐
- Java初学者常用开发工具介绍
- Java 开发工具介绍
- java初学者常用开发工具介绍
- Java开发工具介绍
- 初学java常用开发工具介绍
- 免费的 Java GUI 开发工具 Netbeans 介绍
- 1:java集成开发工具Eclipse介绍
- java开发环境搭建和开发工具介绍
- JavaSe 3. java常用类库,包介绍及开发工具
- JAVAWEB开发之Struts2详解(一)——Struts2框架介绍与快速入门、流程分析与工具配置以及Struts2的配置以及Action和Result的详细使用
- JavaWEB——S01E01_开发工具介绍
- Java开发工具介绍
- 随笔(二):Java开发工具介绍
- java初学者常用开发工具介绍
- 初学java常用开发工具介绍
- Java开发工具介绍
- 免费的 Java GUI 开发工具 Netbeans 介绍
- Java新手看招 常用开发工具介绍
- Java新手看招 常用开发工具介绍
- java开发工具简单介绍