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

kro*_*old 10 java intellij-idea

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

Cra*_*der 5

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

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


Sea*_*oyd 1

我会采用 AOP 方式:

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

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

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());
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

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

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