动手实现lombok的@Getter和@Setter
使用lombok的@Getter和@Setter
作为一个Java 库,以简单的注解方式避免工程中的繁琐重复的代码。常用的注解有@Getter @Setter @Slf4j等。
官网是https://projectlombok.org/。
// 配置Maven依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
// 类中使用注解
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Student{
private String name;
private int age;
}
使用反编译工具打开Student.class后可发现,lombok自动生成了get set方法,并且在生成的class类中没有lombok相关的类。
lombok生成代码原理
lombok通过jdk实现的JSR 269: Pluggable Annotation Processing API (编译期的注解处理器) ,在编译时把lombok的注解转换成Java代码,相当于在编译时对代码进行修改。
javac编译的的过程大概有以下几个步骤
1、词法分析
2、语法分析
3、填充符号表
4、插入式注解处理器处理
5、语义分析
6、解语法糖
7、生成字节码
lombok实现了插入式注解处理器,通过它来读取、修改、添加抽象语法树中的任意元素。
动手实现lombok的@Getter和@Setter
git clone git@gitee.com:viturefree/lombok.git
# 打开lombok下的lombok项目,编译构建以及安装jar包到本地(供lombok-test使用)
mvn clean install
在target目录下生成了jar包
打开lombok下的lombok-test项目,直接运行
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Setter {
}
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Getter {
}
@interface表示注解类型,一个注解是一个类。
@Retention用来修饰注解,是注解的注解,称为元注解。
RetentionPolicy有3个值:SOURCE、CLASS、RUNTIME。
@Retention(RetentionPolicy.SOURCE)修饰的注解,表示注解的信息保留在java源文件中。
@Retention(RetentionPolicy.CLASS)修饰的注解,表示注解的信息保留在class文件中。
@Retention(RetentionPolicy.RUNTIME)修饰的注解,表示注解的信息保留在class文件中,在运行时会被JVM读取。
注解@Target也是元注解,ElementType值为:ANNOTATION_TYPE、CONSTRUCTOR、FIELD LOCAL_VARIABLE、METHOD、PACKAGE、PARAMETER、TYPE。
@Target(ElementType.TYPE)表示该注解作用于类型。
...
public class GetterProcessor extends AbstractProcessor {
...
private Name getNewMethodName(Name name) {
String s = name.toString();
return names.fromString("get" + s.substring(0, 1).toUpperCase() + s.substring(1, name.length()));
}
}
...
public class SetterProcessor extends AbstractProcessor {
...
private Name getNewMethodName(Name name) {
String s = name.toString();
return names.fromString("set" + s.substring(0, 1).toUpperCase() + s.substring(1, name.length()));
}
}
AbstractProcessor是抽象注解处理器类,GetterProcessor和SetterProcessor类继承了它。
getNewMethodName用于生成抽象语法树中get或者set方法名字,即get或者set+属性首字母大写。