繁体   English   中英

如何添加@NotNull注解的运行时处理

[英]How to add run-time processing of @NotNull annotation

我很惊讶地看到 IntelliJ 在运行/调试单元测试时实际上在 IDEA 中对 @NotNull 进行了运行时验证。 我是否可以将相同的功能添加到我的 maven 构建中? (我需要什么 jars/jvm 设置?)

IDEA 正在使用自己的检测字节码的方法来添加此类验证。 对于命令行构建,我们提供 javac2 Ant 任务来执行检测(扩展标准 javac 任务)。 如果您从 IDEA 生成 Ant 构建,您将可以选择使用 javac2。

我们还没有提供类似的 Maven 插件,但是有第三方版本可能适合您(虽然,它似乎有点旧)。

我会 go AOP 方式:

首先你需要一个javax.validation兼容的验证器( Hibernate Validator是参考实现)。

现在创建一个具有 Validator 实例的 aspectj 方面,并检查所有方法参数是否存在验证错误。 这是一个快速版本,可帮助您入门:

public aspect ValidationAspect {

    private final Validator validator;

    {
        final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();

    }

    pointcut serviceMethod() : execution(public * com.yourcompany**.*(..));

    before() : serviceMethod(){
        final Method method = (Method) thisJoinPoint.getTarget();
        for(final Object arg : thisJoinPoint.getArgs()){
            if(arg!=null) validateArg(arg,method);
        }
    }

    private void validateArg(final Object arg, final Method method) {
        final Set<ConstraintViolation<Object>> validationErrors = validator.validate(arg);
        if(!validationErrors.isEmpty()){
            final StringBuilder sb = new StringBuilder();
            sb.append("Validation Errors in method ").append(method).append(":\n");
            for (final ConstraintViolation<Object> constraintViolation : validationErrors) {
                sb.append(" - ").append(constraintViolation.getMessage()).append("\n");
            }
            throw new RuntimeException(sb.toString());
        }
    }

}

使用aspectj-maven-plugin将该方面编织到您的测试和/或生产代码中。

如果您只想将此功能用于测试,则可以将 aspectj-plugin 执行放在配置文件中。

有一个与 IntelliJ 功能密切相关的 maven 插件,目前位于https://github.com/osundblad/intellij-annotations-instrumenter-maven-plugin 在 CrazyCoder 的回答中首先提到的IDEA-31368票证下对此进行了讨论。

您可以在 JUnit 测试中进行注释验证。

import java.util.Set;

import javax.validation.ConstraintViolation;

import junit.framework.Assert;

import org.hibernate.validator.HibernateValidator;
import org.junit.Before;
import org.junit.Test;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

public class Temp {
    private LocalValidatorFactoryBean localValidatorFactory;

    @Before
    public void setup() {
        localValidatorFactory = new LocalValidatorFactoryBean();
        localValidatorFactory.setProviderClass(HibernateValidator.class);
        localValidatorFactory.afterPropertiesSet();
    }
    @Test
    public void testLongNameWithInvalidCharCausesValidationError() {
        final ProductModel productModel = new ProductModel();
        productModel.setLongName("A long name with\t a Tab character");
        Set<ConstraintViolation<ProductModel>> constraintViolations = localValidatorFactory.validate(productModel);
        Assert.assertTrue("Expected validation error not found", constraintViolations.size() == 1);
    }
}

如果您的毒药是 Spring,请查看这些Spring 单元测试

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM