[英]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.