创建自定义注释时 AnnotationProcessor 与 ConstraintValidator 的用途是什么

What is the use of AnnotationProcessor vs ConstraintValidator while creating custom annotation

我需要创建一个自定义注释,该注释在应用于方法时会针对各种检查检查并验证输入参数(原始和非原始)。如果检查失败,应该 return 直接显示错误消息。

在搜索过程中,我发现在创建自定义注释时会使用 AbstractProcessor 和 ConstraintValidator。作为创建自定义注释的新手,我想了解如何继续实施我的问题陈述。

首先,你需要明白你在谈论两件不同的事情。

TL;DR:编译时间与 运行-时间 - 你需要 运行-时间


注释处理器 是一个抽象术语,用于标识在编译期间 运行s 的进程,并且能够 扫描 源文件,扩展名为 .java 的文件。

根据任意检查,注释处理器 实现可能会抛出警告,甚至是停止编译任务的错误。
示例:"I noticed someone passed a null value to my method, it's a error! Stop everything!"

实现注释处理器的起点是AbstractProcessor基础class,或Processor接口(documentation).
ConstraintValidator 实现不同,您还需要通过 处理器元数据 文件显式注册它,该文件必须位于生成的 [=17= 中的标准目录下]神器

META-INF/services/javax.annotation.processing.Processor

创建 注释处理器 所需的内容已包含在标准 JDK 中。您不需要外部依赖项。


另一方面,ConstraintValidator 标识与 Validation API 模块一起提供的接口,在包 javax.validation 下.这个 API 有不同的实现方式,但最常用的是 Hibernate Validator (documentation).
此接口提供的验证在运行时间被验证。

与注释处理器不同,验证 API 实现必须手动提供,例如

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.15.Final</version>
</dependency>

你写了

when applied over a method checks and validates the input parameters (Primitive and non-primitive) against various checks

看来你需要写运行-时间检查,这意味着验证API是要走的路。

AbstractProcessor and ConstraintValidator 的用例完全不同。让我们深入探讨一下。


AbstractProcessor

a convenient superclass for most concrete annotation processors

那么什么是注解处理器,它们的用例是什么?如果你想在编译时基于注解生成新的源代码,你可以使用注解处理器。它们作为编译过程的一部分提供,并通过 Java 编译器调用。例如 a static metamodel geneartors for JPA.


A ConstraintValidator 可用于确保在运行时,属性、参数等满足特定约束。最流行的约束之一是 @NotNull. At runtime, some piece of code, a constraint validator, checks that all fields/parameters annotated with @NotNull actually are not null. If you want to write your own constraint, you need to write an annotatation, as well as a processor to satisfy your constraint. This tutorial on dzone.com 概述了创建自定义注释的过程以及相应的 ConstraintValidator.