Hibernate Validator 中文操作指南
13. Annotation Processor
你是否曾经无意中做了类似这样的事情?
-
在不受支持的数据类型中指定约束注释(例如使用 @Past 注释 String)
-
注释 JavaBean 属性的 setter(而不是 getter 方法)
-
使用约束注释注释静态字段 / 方法(不支持)?
那么 Hibernate Validator 注解处理器正适合你。它通过插入到构建过程中并在错误使用约束注解时引发编译错误,从而帮助防止此类错误。
你可以在 Sourceforge 的分发包中或在通常的 Maven 存储库(例如 Maven Central)中,使用 GAV org.hibernate.validator:hibernate-validator-annotation-processor:8.0.1.Final 在 Hibernate Validator Annotation Processor 中找到它。 |
13.1. Prerequisites
Hibernate 验证器注释处理器基于 JSR 269 定义的“可插拔注释处理 API”,它属于 Java 平台的一部分。
13.2. Features
截至 Hibernate Validator 8.0.1.Final,Hibernate Validator 注解处理器检查:
-
约束注释允许用于注释元素的类型
-
只用约束注释注释非静态字段或方法
-
只对非基本字段或方法使用 @Valid 注释
-
只对约束注释进行注释的方法是有效的 JavaBeans getter 方法(也可以参见下文)
-
只对约束注释进行注释的注释类型是约束注释本身
-
使用 @GroupSequenceProvider 对动态默认组顺序的定义有效
-
注释参数值是有意义且有效的
-
继承层级中的方法参数约束遵守继承规则
-
继承层级中的方法返回值约束遵守继承规则
13.3. Options
可以使用以下 processor options 控制 Hibernate 验证器注释处理器的行为:
diagnosticKind
控制约束问题报告的方式。必须是枚举 javax.tools.Diagnostic.Kind 中某个值字符串表示,例如 WARNING 。如果 AP 检测到约束问题,则 ERROR 值将导致编译停止。默认为 ERROR 。
methodConstraintsSupported
控制方法中是否允许任何类型的约束。使用 Hibernate Validator 支持的方法级别约束时,必须将其设置为 true 。可以将其设置为 false ,以仅允许 Jakarta Bean Validation API 定义的 JavaBeans getter 方法中存在约束。默认为 true 。
verbose
控制是否显示详细处理信息,此功能可用于调试。必须为 true 或 false 。默认为 false 。
13.4. Using the Annotation Processor
本部分详细说明了如何将 Hibernate Validator 注解处理器集成到命令行构建(Maven、Ant、javac)以及基于 IDE 的构建(Eclipse、IntelliJ IDEA、NetBeans)中。
13.4.1. Command line builds
13.4.1.1. Maven
要使用 Maven 和 Hibernate Validator 注解处理器,请通过 annotationProcessorPaths 选项进行设置,如下所示:
<project>
[...]
<build>
[...]
<plugins>
[...]
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>8.0.1.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
[...]
</plugins>
[...]
</build>
[...]
</project>
13.4.1.2. Gradle
使用 Gradle 时,足以将注释处理器引用为 annotationProcessor 依赖项。
dependencies {
annotationProcessor group: 'org.hibernate.validator', name: 'hibernate-validator-annotation-processor', version: '8.0.1.Final'
// any other dependencies ...
}
13.4.1.3. Apache Ant
类似于直接使用 javac,可以在调用 javac task 时将注释处理器添加为编译器参数,以用于 Apache Ant:
<javac srcdir="src/main"
destdir="build/classes"
classpath="/path/to/validation-api-3.0.2.jar">
<compilerarg value="-processorpath" />
<compilerarg value="/path/to/hibernate-validator-annotation-processor-8.0.1.Final.jar"/>
</javac>
13.4.1.4. javac
使用 javac 在命令行上编译时,使用“processorpath”选项指定 JAR hibernate-validator-annotation-processor-8.0.1.Final.jar,如下面的清单所示。编译器将自动检测到该处理器并在编译期间调用它。
13.4.2. IDE builds
13.4.2.1. Eclipse
只要安装了 M2E Eclipse plug-in,为按上述方式配置的 Maven 项目自动设置注释处理器。
对于普通 Eclipse 项目,请遵循以下步骤设置注解处理器:
-
右键单击你的项目,选择“属性”
-
转到“Java 编译器”并确保将“编译器遵从级别”设为“1.8”。否则,处理器将不会被激活
-
转到“Java 编译器 - 注解处理”,并选择“启用注解处理”
-
转到“Java 编译器 - 注解处理 - 工厂路径”,并添加 JAR hibernate-validator-annotation-processor-8.0.1.Final.jar
-
Confirm the workspace rebuild
您现在应该在编辑器中看到任何注释问题,这些注释问题显示为普通错误标记,并且在“问题”视图中显示:
13.4.2.2. IntelliJ IDEA
在 IntelliJ IDEA (版本 9 及更高版本)中使用注释处理器时,必须执行以下步骤:
-
转到“文件”,然后转到“设置”
-
展开“编译器”节点,然后展开“注解处理器”
-
选择“启用注解处理”,并将“处理器路径”输入为:/path/to/hibernate-validator-annotation-processor-8.0.1.Final.jar
-
将处理器的完全限定名 org.hibernate.validator.ap.ConstraintValidationProcessor 添加到“注解处理器”列表
-
如果适用,将你的模块添加到“处理的模块”列表
然后再编译您的项目,然后应显示任何错误的约束注释:
13.4.2.3. NetBeans
NetBeans IDE 支持在 IDE 构建中使用注释处理器。为此,请执行以下操作:
-
右键单击你的项目,选择“属性”
-
转到“库”,选择“处理器”选项卡,并添加 JAR hibernate-validator-annotation-processor-8.0.1.Final.jar
-
转到“构建 - 编译”,选择“启用注解处理”和“在编辑器中启用注解处理”。通过指定它的完全限定名 org.hibernate.validator.ap.ConstraintValidationProcessor 来添加注释处理器
然后,任何约束注释问题都将直接在编辑器中标记:
13.5. Known issues
截至 2017 年 7 月,存在以下已知问题:
-
目前不支持容器元素约束。
-
应用于容器的约束,但实际上应用于容器元素(通过 Unwrapping.Unwrap 有效负载或通过标记为 @UnwrapByDefault 的值提取器),无法得到正确支持。
-
有时在 Eclipse 中使用处理器时,无法 properly evaluated 自定义约束。在这些情况下,清理项目可能有帮助。这似乎是 Eclipse JSR 269 API 实现的问题,但这里需要进一步调查。
-
在 Eclipse 中使用处理器时,动态默认组顺序定义的检查不起作用。经进一步调查,这似乎是 Eclipse JSR 269 API 实现的问题。