与反应堆核心链交互的多个注释方面导致方法调用中的IllegalStateException

时间:2019-06-27 13:17:34

标签: java spring-boot annotations core reactor

我正在从事Spring Web反应项目,目前正在实现针对请求的不同指标的收集。事实证明,与我的rest-controller方法的Mono返回对象进行交互的多个@Around注释会导致Spring引发IllegalStateException。

我正在将Java 11与Spring Boot 2.1.5-RELEASE一起使用

我逐步浏览了Spring代码,并试图找出到底出了什么问题,在我看来,当在ProceedingJoinPoint上调用proce()时,spring aop逻辑会混淆不同批注的参数。具体来说,AbstractApsectJAdvice行684中的getUserAttribute调用返回null,并且似乎提供了错误的参数。我还尝试过更改方面方法的顺序,但没有成功。

以下方法是有问题的其余处理程序,@TimedMono和@HostLanguageRequestCounted批注都添加到了反应堆链中

    @Counted("statistics_incoming_requests")
    @TimedMono("statistics_incoming_requestExecutionTime")
    @PostMapping("/translate/{id}/{field}")
    @HostLanguageRequestCounted("statistics_incoming_hostLanguageRequestCount")
    public Mono<TranslationResponseBody> getTranslation(@PathVariable String id,
            @PathVariable String field,
            @RequestBody TranslationRequestBody requestBody) {
        return translateService.translate(id, requestBody.getTargetLanguage(), requestBody.getText(), field);
    }

这是处理TimedMono批注的方法:

      @Around(value = "@annotation(timed)")
    @Order(2)
    @SuppressWarnings("checkstyle:illegalThrows")
    public Mono<?> timeExecution(ProceedingJoinPoint pjp, TimedMono timed) throws Throwable {
        Long tStart = System.nanoTime();
        Object m = pjp.proceed();
        long tEnd = System.nanoTime();
        if (!(m instanceof Mono)) {
            throw (new Exception("Method must return a mono object"));
        }

        Mono<?> mono = (Mono) m;
        Consumer<Object> stopTimer = obj -> {
            meterRegistry.timer(timed.value())
                    .record(tEnd - tStart, TimeUnit.NANOSECONDS);
        };
        return mono.doOnError(stopTimer).doOnNext(stopTimer);
    }

以及处理HostLanguageRequestCounted批注的方法:

    @Around(value = "@annotation(hostLanguageRequestCounted)")
    @Order(1)
    public Object gatherTenantMetrics(ProceedingJoinPoint pjp,
            HostLanguageRequestCounted hostLanguageRequestCounted) throws Throwable {
        Optional<TranslationRequestBody> body = HostLanguageRequestCountedMetricAspect
                .getArgumentOfType(TranslationRequestBody.class, pjp);
        return Mono.subscriberContext()
                .flatMap(ctx -> {
                    log.info(ctx.toString());
                    return Mono.just(ctx.get("host"));
                }).flatMap(host -> {
                    if (host != null && body.isPresent() && body.get().getTargetLanguage() != null) {
                        String metricKey = hostLanguageRequestCounted.value();
                        metricKey += "_" + host.toString().toLowerCase();
                        metricKey += "_" + body.get().getTargetLanguage().toLowerCase();
                        meterRegistry.counter(metricKey).increment();
                    }
                    try {
                        return (Mono<?>) pjp.proceed();
                    } catch (Throwable t) {
                        return Mono.error(t);
                    }
                });
    }

    private static <T> Optional<T> getArgumentOfType(Class<T> clazz, ProceedingJoinPoint pjp) {
        return Arrays.stream(pjp.getArgs())
                .filter((arg) -> clazz.isAssignableFrom(arg.getClass()))
                .map((obj) -> (T) obj).findFirst();
    }

在其中引发异常(返回(单声道)pjp.proceed();)

引发的异常如下:

  

java.lang.IllegalStateException:需要绑定2个参数,但仅绑定1个(在调用中未绑定JoinPointMatch)       在org.springframework.aop.aspectj.AbstractAspectJAdvice.argBinding(AbstractAspectJAdvice.java:605)       在org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)       在org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)       在org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)

堆栈跟踪中的下一个条目是我的代码行。

这是春季的实际错误,还是我做错了什么?当我删除其中一个注释时,另一个注释将没有问题地执行。

0 个答案:

没有答案