在 @Async 注释的情况下,Aspect 中的验证异常被吞没
Validation exceptions in Aspect are swallowed in case of @Async annotation
我有一个方法定义为:
@Async("queryTaskExecutor")
@RateLimitation(rateSize = 10)
public Future<RunQueryCommandResult> execute(final Path xmlPath,
final Boolean calculateAlreadyAllowedTraffic,
final String sessionId,
final boolean isQueryFromAFA,
final String mode) {}
RateLimitation 是针对每个方法执行的 RateLimiter 验证的自定义注释。
触发方面的注释定义为:
@Aspect
public class RateLimitationAspect {
private static final Logger log = LoggerFactory.getLogger(RateLimitationAspect.class);
@Autowired
RateLimitationValidator rateLimitationValidator;
public RateLimitationAspect() {
}
@Before("@annotation(rateLimitation)")
public void aroundRateLimitationAction(JoinPoint joinPoint, RateLimitation rateLimitation) throws Throwable {
MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
Method method = methodSignature.getMethod();
log.info("Validating rate limitation on method " + method.getName());
if (!this.rateLimitationValidator.isValid(method, (ConstraintValidatorContext)null)) {
throw new IllegalStateException(MessageFormat.format("Calling method [{0}] reached the maximum permitted calls per second, request is denied.", method.toString()));
}
}
}
我创建了一个测试来检查汇率验证:
@Test(expected = IllegalStateException.class)
public void test_execute_command_service_in_forbidden_amount_parallel() {
IntStream.range(1, 40).parallel().forEach(i ->
runQueryCommandService.execute(XML_PATH, false, VALID_ALL_FIREWALLS_SESSION, false, QUERY)
);
}
测试失败,因为没有抛出 IllegalStateException。
当我调试测试时,由于验证错误,IllegalStateException 确实在方面代码中被抛出。
吞下 llegalStateException。
如果我从方法定义中删除 @Async 注释,则测试正常。
请帮忙。
问题是调用带有@Async 注释的方法不会触发Spring bean 代理。
我通过更改测试来调用控制器(调用被测试服务的那个)来解决它。
然后按预期抛出并捕获异常。
我有一个方法定义为:
@Async("queryTaskExecutor")
@RateLimitation(rateSize = 10)
public Future<RunQueryCommandResult> execute(final Path xmlPath,
final Boolean calculateAlreadyAllowedTraffic,
final String sessionId,
final boolean isQueryFromAFA,
final String mode) {}
RateLimitation 是针对每个方法执行的 RateLimiter 验证的自定义注释。 触发方面的注释定义为:
@Aspect
public class RateLimitationAspect {
private static final Logger log = LoggerFactory.getLogger(RateLimitationAspect.class);
@Autowired
RateLimitationValidator rateLimitationValidator;
public RateLimitationAspect() {
}
@Before("@annotation(rateLimitation)")
public void aroundRateLimitationAction(JoinPoint joinPoint, RateLimitation rateLimitation) throws Throwable {
MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
Method method = methodSignature.getMethod();
log.info("Validating rate limitation on method " + method.getName());
if (!this.rateLimitationValidator.isValid(method, (ConstraintValidatorContext)null)) {
throw new IllegalStateException(MessageFormat.format("Calling method [{0}] reached the maximum permitted calls per second, request is denied.", method.toString()));
}
}
}
我创建了一个测试来检查汇率验证:
@Test(expected = IllegalStateException.class)
public void test_execute_command_service_in_forbidden_amount_parallel() {
IntStream.range(1, 40).parallel().forEach(i ->
runQueryCommandService.execute(XML_PATH, false, VALID_ALL_FIREWALLS_SESSION, false, QUERY)
);
}
测试失败,因为没有抛出 IllegalStateException。 当我调试测试时,由于验证错误,IllegalStateException 确实在方面代码中被抛出。
吞下 llegalStateException。 如果我从方法定义中删除 @Async 注释,则测试正常。 请帮忙。
问题是调用带有@Async 注释的方法不会触发Spring bean 代理。 我通过更改测试来调用控制器(调用被测试服务的那个)来解决它。 然后按预期抛出并捕获异常。