如何在Gradle了中自定义一个注解处理器

2024-08-25 07:08

本文主要是介绍如何在Gradle了中自定义一个注解处理器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文主要记录了两部分

  1. Java中预定义好的Annotation的类型
  2. 如何实现一个自定义注解和使用

Java中预定义好的Annotation的类型

Java 语言中自定义的一些注释
  1. @Deprecate
  2. @Override
  3. @SuppressWarnings,告诉编译器,禁止抛出一些警告。Java中有两大类警告deprecationunchecked. 例如,@SuppressWarnings({"unchecked", "deprecation"})
  4. @SafeVarargs,当构造器和方法中,认为不会出现不安全的参数。
  5. @FunctionalInterface,在Java SE8 中,被声明为函数式的接口。
能够用于注射中的注释
  1. @Retention@Retention标记注释是如何存储的
    1. RetentionPolicy.SOURCE – 标记该注释只会在源代码中,而不会出现在编译后的文件中;
    2. RetentionPolicy.CLASS – 标记该注释会在编译后保留,但是在JVM中会被忽视;
    3. RetentionPolicy.RUNTIME – 标记该注释会保留在JVM中,会在程序运行的时候使用。
  2. @Documented @Documented 文档注释
  3. @Target @Target 标记被标记的注释能够用于Java中的那些字段和属性上
    • ElementType.ANNOTATION_TYPE 可以用于注释上.
    • ElementType.CONSTRUCTOR 可以用于构造器
    • ElementType.FIELD 可以用于属性字段
    • ElementType.LOCAL_VARIABLE 可以用于本地变量.
    • ElementType.METHOD 可以用于方法.
    • ElementType.PACKAGE can be applied to a package declaration.
    • ElementType.PARAMETER 可以用于方法的形参
    • ElementType.TYPE 可以用于Class中的任意元素上.
  4. @Inherited @Inherited 标示可以从父类的注解中继承属性(默认为fasle)。当用户使用该注解,如何标记的类上没有任何的注解,则会从父类中查找。该注解只能用于Class级别的注解。
  5. @Repeatable @Repeatable Java8之后,表示该注解可以在同一个元素上使用多次,详见 Repeating Annotations.

如何自定义实现一个注解处理器

下面的例子是一个类似于Lombok中的注解。自定义一个@BuilderProperty注解,作用于Filed属性上,用于生成Builder构造器模式

当然了,Lombok 已经有了@Builder 注解用于实现我们的需求,但是这里主要是熟悉这个流程

public class Person {private int age;private String name;@BuilderPropertypublic void setAge(int age) {this.age = age;}@BuilderPropertypublic void setName(String name) {this.name = name;}
}
// 生成效果是可以使用
Person person = new PersonBuilder().setAge(23).setName("zhangsan").build();

整理一个晚上,也算是最终实现了,具体里面的细节可能还需要各位亲们自己完善一下。

运行环境

  1. Gradle 6.6+
  2. Java 11+

参考的教程中是通过maven构建的多模块来构建的,我这里参考了一些其他资料,如下的设计可能更加的合理。

将项目分为3个模块。 annotation/annotation-processor/demo。

  1. annotation 模块用于编写注解
  2. annotation-processor 模块用于编写对应的注解处理器
  3. demo 用于实际上使用的注解的样例代码

因为我们的注解主要是用于生成一个Java源文件,所以,我们只希望在编译的过程中,才使用。所以项目之间的依赖关系如下

#	annotation build.gradle
dependencies {
}# annotation-processor build.gradle
dependencies {compileOnly project(':annotation')compileOnly 'com.google.auto.service:auto-service:1.0-rc2'annotationProcessor 'com.google.auto.service:auto-service:1.0-rc2'
}# demo build.gradle
dependencies {compileOnly project(':annotation')annotationProcessor project(':annotation-processor')
}

实现一个注解处理器的两个步骤:1. 自定义实现 AbstractProcessor接口;2. 另外一个就是注册自定义的注解处理器注解。上面的:auto-service依赖就是Google提供的注解和注解处理器来简化我们的注册流程。

annotation 模块下的注解代码如下:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface BuilderProperty {
}

Annotation-processor 模块下的代码如下:

@SupportedAnnotationTypes("top.ilovestudy.annotation.BuilderProperty")
@SupportedSourceVersion(SourceVersion.RELEASE_11)
@AutoService(Processor.class)
public class BuilderProcessor extends AbstractProcessor {@Overridepublic boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {//    ..... 	 具体的实现就查看下方提供的源码吧return true;}
}

@SupportedAnnotationTypes 说明注解处理器用来绑定哪一个注解,@SupportedSourceVersion 用来指定支持的Java版本,下面的 @AutoService(Processor.class) 就是google提供的简化注册的注解。如果不想引用google的注解,可以查看文献5中,注册的方法。

还有很多,就不啰嗦了,直接提供源码用于参考,点击下方下载

如果觉得有些帮助,点个赞再走吧😊。Gitee地址/ 项目提交快照.zip

Gitee 上分支上的代码可能会随着不断的提交而变的不那么的清晰,建议直接下载对应的zip包文件,更加的清晰。

参考文献


  1. 疯狂Java讲义(第2版)-李刚编著-微信读书
  2. An introductory guide to annotations and annotation processors
  3. Java Annotation Processing and Creating a Builder | Baeldung
  4. Predefined Annotation Types (The Java™ Tutorials > Learning the Java Language > Annotations)
  5. (看完之后觉得比较全且质量较高的中文资料)自定义Java注解处理器

这篇关于如何在Gradle了中自定义一个注解处理器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1104886

相关文章

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

SpringBoot 获取请求参数的常用注解及用法

《SpringBoot获取请求参数的常用注解及用法》SpringBoot通过@RequestParam、@PathVariable等注解支持从HTTP请求中获取参数,涵盖查询、路径、请求体、头、C... 目录SpringBoot 提供了多种注解来方便地从 HTTP 请求中获取参数以下是主要的注解及其用法:1

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java利用@SneakyThrows注解提升异常处理效率详解

《Java利用@SneakyThrows注解提升异常处理效率详解》这篇文章将深度剖析@SneakyThrows的原理,用法,适用场景以及隐藏的陷阱,看看它如何让Java异常处理效率飙升50%,感兴趣的... 目录前言一、检查型异常的“诅咒”:为什么Java开发者讨厌它1.1 检查型异常的痛点1.2 为什么说

聊聊springboot中如何自定义消息转换器

《聊聊springboot中如何自定义消息转换器》SpringBoot通过HttpMessageConverter处理HTTP数据转换,支持多种媒体类型,接下来通过本文给大家介绍springboot中... 目录核心接口springboot默认提供的转换器如何自定义消息转换器Spring Boot 中的消息

Python自定义异常的全面指南(入门到实践)

《Python自定义异常的全面指南(入门到实践)》想象你正在开发一个银行系统,用户转账时余额不足,如果直接抛出ValueError,调用方很难区分是金额格式错误还是余额不足,这正是Python自定义异... 目录引言:为什么需要自定义异常一、异常基础:先搞懂python的异常体系1.1 异常是什么?1.2

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

C语言自定义类型之联合和枚举解读

《C语言自定义类型之联合和枚举解读》联合体共享内存,大小由最大成员决定,遵循对齐规则;枚举类型列举可能值,提升可读性和类型安全性,两者在C语言中用于优化内存和程序效率... 目录一、联合体1.1 联合体类型的声明1.2 联合体的特点1.2.1 特点11.2.2 特点21.2.3 特点31.3 联合体的大小1

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束