Javax验证实现

Javax验证实现,java,validation,annotations,Java,Validation,Annotations,我试图为局部变量创建自定义注释,但我不明白像@NotNull或@Null这样的注释实际上是如何在代码中实现的。我查看了实际的文件,这里是@NotNull: @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) @Documented @Constraint(validatedBy = { }) public @interface NotNull { String m

我试图为局部变量创建自定义注释,但我不明白像
@NotNull
@Null
这样的注释实际上是如何在代码中实现的。我查看了实际的文件,这里是
@NotNull

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { })
public @interface NotNull {

    String message() default "{ javax.validation.constraints.NotNull.message }";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };

    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        NotNull[] value();
    }
}
@Target({方法、字段、注释\类型、构造函数、参数})
@保留(运行时)
@记录
@约束(validatedBy={})
公共@interface NotNull{
String message()默认值“{javax.validation.constraints.NotNull.message}”;
类[]组()默认值{};

类通常需要提供用于验证的validatedBy类

@Target(TYPE)
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {TicketPresenceValidator.class})
public @interface AtLeastOneTicket {
}


public class TicketPresenceValidator implements ConstraintValidator<AtLeastOneTicket, TicketInfo> {
 @Override
 public void initialize(TicketInfo constraintAnnotation) {
 }

 @Override
 public boolean isValid(TicketInfo ticketInfo, 
                        ConstraintValidatorContext context) {
    return ticketInfo.getSize() != 0;
 }
}
@Target(类型)
@保留(运行时)
@记录
@约束(validatedBy={TicketPresenceValidator.class})
公共@interface AtleSofticket{
}
公共类TicketPresenceValidator实现ConstraintValidator实现

然后将约束和验证器链接在一起

实际检查发生在哪里

如果仔细查看-
javax.validation.constraints.@NotNull
源代码(已粘贴),
@Constraint(validatedBy={})
保留为空,即未指定实现类。这是因为javax验证jar类似-
validation-api-2.0.1.Final.jar
etc基本上是一个bean验证标准(一组没有实现的接口、注释等).这些约束的实现由hibernate、Oracle等供应商提供

列出了三个标准,这样您就应该知道您使用的是哪个版本的bean验证标准

因此,如果您有实现jar,如-
hibernate-validator-6.0.10.Final.jar
,您也可以看到实现源代码

/*
 * Hibernate Validator, declare and validate application constraints
 *
 * License: Apache License, Version 2.0
 * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
 */
package org.hibernate.validator.internal.constraintvalidators.bv;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraints.NotNull;

/**
 * Validate that the object is not {@code null}.
 *
 * @author Emmanuel Bernard
 */
public class NotNullValidator implements ConstraintValidator<NotNull, Object> {

    @Override
    public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
        return object != null;
    }
}
/*
*Hibernate验证器,声明和验证应用程序约束
*
*许可证:Apache许可证,版本2.0
*请参阅根目录或中的license.txt文件。
*/
包org.hibernate.validator.internal.constraintvalidators.bv;
导入javax.validation.ConstraintValidator;
导入javax.validation.ConstraintValidatorContext;
导入javax.validation.constraints.NotNull;
/**
*验证对象是否不是{@code null}。
*
*@作者伊曼纽尔·伯纳德
*/
公共类NotNullValidator实现ConstraintValidator{
@凌驾
公共布尔值有效(对象对象,ConstraintValidatorContext ConstraintValidatorContext){
返回对象!=null;
}
}
现在,您必须了解搜索/解析bean验证标准的实现是一项复杂的任务,请参阅-
javax.validation.ValidationProviderResolver
&如果开发人员使用Spring Boot等框架,这个过程会变得很容易

inigo skimmer的Answer也做这两件事-为自定义验证声明注释,实现实际验证,并通过在-
@Constraint(validatedBy={TicketPresenceValidator.class})
中硬编码validator类解析验证程序,从而避免复杂的验证实现搜索逻辑

您必须了解的另一部分是,您的验证器是类型为
javax.validation.ConstraintValidator
的,因此请阅读javadoc作为您需要提供给

其他可参考的链接


是的,我明白了这一点,我实际上做了一个使用该验证器的自定义注释。但我想知道
@NotNull
是如何具体实现的,因为我在任何地方都没有看到任何验证器。更新了答案,解释了内置约束。