动手实现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+属性首字母大写。

参考资料

浅析Lombok原理并动手编写@Getter与@Setter的简单实现

posted on 2022-03-19 12:04  王景迁  阅读(1541)  评论(0编辑  收藏  举报

导航