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

时间:2011-08-10 09:03:40

标签: java intellij-idea

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

4 个答案:

答案 0 :(得分:5)

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

We don't provide similar Maven plug-in yet,但there is third-party version可能对您有用(但似乎有点旧)。

答案 1 :(得分:1)

我会采用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执行放在配置文件中。

答案 2 :(得分:0)

您可以在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 Unit Tests

答案 3 :(得分:0)

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