在日常的Java开发中,最常见的就是Javabean对象,常常一个对象中有很多,私有属性,我们需要进行setter和getter的操作,如下
public class Student { private Integer id; private String name; private Integer age; private Integer sex; private String address; private Float score; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Integer getSex() { return sex; } public void setSex(Integer sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Float getScore() { return score; } public void setScore(Float score) { this.score = score; }}这样的代码,显得很臃肿,尤其是当我们再添加属性,或者修改属性名称时,都需要手动更改或新增setter和getter方法,维护起来比较麻烦,因此很多开发者在日常使用过程中,都使用lombok工具来简化相关代码,代码如下
@Datapublic class Student { private Integer id; private String name; private Integer age; private Integer sex; private String address; private Float score;}lombok工具常见使用方法
以idea举例,我们使用lombok首先需要安装lombok插件,如下图

然后在使用的项目中引入依赖(以maven举例)
<dependency> <groupId>org.projectlombokgroupId> <artifactId>lombokartifactId> <version>1.18.12version> <scope>providedscope>dependency>接下来我们就可以使用lombok工具提供的注解功能,进行开发。下面对常见的lombok工具注解进行介绍:
@Getter // 生成getter方法@Setter // 生成setter方法@ToString // 自动重写 toString() 方法,会印出所有变量@EqualsAndHashCode // 自动生成equals和hashcode方法@NoArgsConstructor // 生成一个没有参数的构造器@AllArgsConstructor // 生成一个包含所有参数的构造器@RequiredArgsConstructor // 生成一个包含 "特定参数" 的构造器(特定参数指的是那些有加上 final 修饰词的变量们)@Data //这个注解,等于同时加了@Getter、@Setter、@ToString、@EqualsAndHashCode、@RequiredArgsConstructor注解@Builder // 自动生成流式 set 值写法@Slf4j //自动生成该类的 log 静态常量,直接通过log写日如下图

为什么使用了注解就可以做到这些功能?
对于代码增强,一般有两种方式,一种运行时增强,例如spring的aop,在运行时,对代码做功能增强;另一种是编译器增强,即编译时,通过字节码技术,将相应的代码植入到class中,lombok就采用两编译器增强。
上面我们对student这个类,加入@Data注解,编译后,我们查看下class文件,发现getter方法、setter方法、tostring方法等都写了相关代码,如下图


原理
针对运行期增强,一般基于动态代理、反射技术实现,性能相对损耗大;编译器增强,一般基于Annotation Processing Tool(APT技术在JDK8中已经彻底删除)以及Pluggable Annotation Processing API技术。
因此我们主要看看Pluggable Annotation Processing API技术,自从Java 6起,javac就支持“JSR 269 Pluggable Annotation Processing API”规范,只要程序实现了该API,就能在javac运行的时候得到调用。
插件化注解处理API的使用步骤大概如下:
1、自定义一个Annotation Processor,需要继承javax.annotation.processing.AbstractProcessor,并覆写process方法。2、自定义一个注解,注解的元注解需要指定@Retention(RetentionPolicy.SOURCE)。3、需要在声明的自定义Annotation Processor中使用javax.annotation.processing.SupportedAnnotationTypes指定在第2步创建的注解类型的名称(注意需要全类名,"包名.注解类型名称",否则会不生效)。4、需要在声明的自定义Annotation Processor中使用javax.annotation.processing.SupportedSourceVersion指定编译版本。5、可选操作,可以通在声明的自定义Annotation Processor中使用javax.annotation.processing.SupportedOptions指定编译参数。6、通过服务注册指定,META-INF/services/javax.annotation.processing.Processor文件中添加 前面定义AnnotationProcessor下面我们按照上面步骤来演示一下:
自定义注解解析器(此处可以通过asm字节码技术写入新方法等,本文不介绍字节码技术,有兴趣的可以研究)
@SupportedAnnotationTypes(value = {"com.example.demo.plugin.Demo"})@SupportedSourceVersion(value = SourceVersion.RELEASE_8)public class AnnotationProcessor extends AbstractProcessor { @Override public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) { System.out.println("Log in AnnotationProcessor.process"); for (TypeElement typeElement : annotations) { System.out.println(typeElement); } System.out.println(roundEnv); return true; }}自定义注解
@Retention(RetentionPolicy.SOURCE)@Target(ElementType.TYPE)public @interface Demo {}使用spi注入注解解析器

使用注解

编写测试用例
public class App { public static void main( String[] args ) { System.out.println( "Hello World!" ); Student student = new Student(); }}运行结果如下,可以看到编译期AnnotationProcessor生效了
Log in AnnotationProcessor.processcom.example.Demo[errorRaised=false, rootElements=[com.example.Demo, com.example.App, com.example.Student], processingOver=false]Log in AnnotationProcessor.process[errorRaised=false, rootElements=[], processingOver=true]注意:如果出现下列报错,可以将AnnotationProcessor先编译,或者放到jar中即可。
[ERROR] Bad service configuration file, or exception thrown whileconstructing Processor object: javax.annotation.processing.Processor: Provider com.example.demo.plugin.AnnotationProcessor not foundLombok便是通过Pluggable Annotation Processing API来实现代码生成的。
根据上面的原理,我们查看下lombok源码,发现的确如此

Lombok是一个用于简化Java开发的工具,通过注解实现getter、setter等方法的自动创建,避免冗余代码。本文介绍了如何在IDEA中安装Lombok插件,引入依赖,并展示了@Data注解的使用。接着,文章探讨了Lombok的编译时增强原理,解释了其利用Java的Annotation Processing API在编译阶段生成额外代码。最后,简要说明了自定义注解处理器的实现步骤,并提到了处理报错的方法。
441

被折叠的 条评论
为什么被折叠?



