【问题标题】:Validation exceptions in Aspect are swallowed in case of @Async annotation在 @Async 注释的情况下,Aspect 中的验证异常被吞没
【发布时间】:2019-12-06 09:32:20
【问题描述】:

我有一个方法定义为:

  @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的annoration定义为:

@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。 当我调试测试时,由于验证错误,确实在 Aspect 代码中抛出了 IllegalStateException。

llegalStateException 被吞下。 如果我从方法定义中删除 @Async 注释,则测试正在运行。 请帮忙。

【问题讨论】:

  • 顺便说一句,您使用的是基于代理的 AOP 还是 AspectJ AOP?

标签: java spring asynchronous rate-limiting aspect


【解决方案1】:

问题是使用 @Async 注解调用方法不会触发 Spring bean 代理。 我通过更改测试来调用控制器(调用测试服务的那个)来解决它。 然后按预期抛出并捕获异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多