Lombok提供了常用的注解,注解可以放在类上或者属性上,可以在源代码的编译时期自动生成一些代码,达到增强类的功能的作用
运行时解析,如Spring AOP通过反射获取目标类,但也只有在程序运行时才可以获取到,导致运行时效率低,而且无法在编译阶段获取增强的目标类
编译时解析就是指Lombok这种工作方式,在编译代码时实现增强类的目的
把注解与Java编译器结合使用的两种方式
编译时解析的两种机制
Lombok 插件在 IntelliJ IDEA上安装步骤 https://projectlombok.org/setup/intellij
File > Settings > Plugins
Browse repositories...
Lombok Plugin
Install plugin
新建一个maven项目,选择
pom.xml中引入lombok依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>provided</scope>
</dependency>
使用Lombok的注解,并查看编译后的class文件,理解Lombok的工作原理
增加entity包,新增Sku实体类,在skuId属性上增加@Getter注解
public class Sku {
@Getter
private Integer skuId;
private String skuName;
@Setter
private Double skuPrice;
private Integer totalNum;
private Double totalPrice;
private Enum skuCategory;
}
类上点击鼠标右键,点击“Recompile 'Sku.java'”
target目录下查看编译后的源代码,自动增加了skuId属性的getter方法,skuPrice的setter方法
@Getter、@Setter直接支持设置访问级别,以及在方法上或者属性上增加注解,在skuName属性上和totalNum属性上增加注解 @Getter(value = AccessLevel.PROTECTED, onMethod_ = {@NotNull})、 @Setter(value = AccessLevel.PRIVATE, onParam_ = {@NotNull}) 再次编译Sku,查看编译后的class文件
@Getter放在final属性上,可以支持懒加载,给Sku实体类增加stock属性,并定义为final Integer 类型,并增加@Getter(lazy = true)
@Getter(lazy = true)
private final Integer stock = 1000;
再次编译Sku类,查看编译后的class文件
从编译文件可以看出stock属性一开始并没有被赋值,而是在调用的时候才会被赋值,实现类懒加载
在Sku类上增加@ToString注解,编译Sku类,查看编译后的class文件
@ToString注解有下面几个属性
修改Sku类上@toString注解为
@ToString(
includeFieldNames = false,
exclude = {"skuId"},
of = {"skuId"}
)
再次编译,查看编译后的文件,方法中不现实属性名,而且of和exclude冲突的情况下,exclude指定的属性会被忽略
修改@ToString注解属性为
@ToString(
includeFieldNames = false,
exclude = {"skuId"},
of = {"skuId","skuPrice"},
doNotUseGetters = false
)
手动给Sku增加 skuPrice的get方法,并增加打印语句
public Double getSkuPrice() {
System.out.println("getter方法被调用");
return skuPrice;
}
增加测试方法
@Test
public void test(){
Sku sku = new Sku();
sku.setSkuPrice(101.0);
System.out.println(sku.toString());
}
执行测试
作用在类上,在Sku类上增加该注解,并重新编译Sku类,查看编译后的文件
同样包含一些属性,用法与@ToString、@Getter、@Setter包含的属性用法一致
大而全的注解,包含了四种注解@Getter、@Setter、@ToString、@EqualsAndHashCode 新建一个Product类
@Data
public class Product {
private Integer productId;
private String productName;
private Double productPrice;
}
编译Product类,查看编译后的文件
包含了getter、setter、toString、equals和hashCode五个方法
弱语言变量,可以接受任何类型的参数
在Product方法中增加构造函数,使用val定义变量并接受不同类型的数据
public Product(){
val productName = "Cell Phone";
val productPrice = 100.0;
val productList = new ArrayList<Product>();
productList.add(new Product());
}
重新编译Product类,查看编译后的文件定义变量都被正确赋值类型
非空检查,可以作用于构造函数的参数中
public Product(@NonNull String productName){
System.out.println(productName);
}
重新编译Product类,查看编译后的文件
增加了对productName的非空判断
@AllArgsConstructor、@NoArgsConstructor可以生成包含全部属性的构造方法和空参构造方法,@RequiredArgsConstructor则可以根据属性生成构造方法
在entity包增加Category类,并增加@AllArgsConstructor、@NoArgsConstructor注解
@AllArgsConstructor
@NoArgsConstructor
public class Category {
private Integer categoryId;
private String categoryName;
}
编译Category类,查看编译后的文件,自动生成了有参数和无参数的构造方法
将Category类的@AllArgsConstructor、@NoArgsConstructor注解注释,将Category类修改为
@RequiredArgsConstructor
public class Category {
private final Integer categoryId;
@NonNull
private String categoryName;
private Category category;
}
将categoryName属性设置为NonNull,将categoryId设置为常量,实例化Category类时这两个参数必传,增加@RequiredArgsConstructor,重新编译Category类
@RequiredArgsConstructor根据属性生成了包含categroyId和categoryName两个属性的构造方法
Lombok优点:
Lombok缺点: