如何使用Spring AOP和WebFlux从joinPoint.proceed()返回的对象

时间:2018-11-04 02:04:01

标签: java spring spring-aop spring-webflux project-reactor

我有一个简单的方面(见下文),带有@Around批注。当应用程序不使用反应性范式时,此方面适用。但是当应用程序返回Mono或Flux时,将无法正常工作。

我需要从方法返回的对象生成一个JSON对象以用作日志,生成事件等。

这是我的代码,可用于非反应性类:

@Around("@annotation(simpleEvent)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint, SimpleEvent simpleEvent) throws Throwable {
    final long start = System.currentTimeMillis();
    Object proceed = null;
    try {
        proceed = joinPoint.proceed();
        // here in the real life the object that transformed in json to do others actions
        System.out.println(proceed);
        final long executionTime = System.currentTimeMillis() - start;
        System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
        return proceed;
    } catch (Exception e) {
        e.printStackTrace(); 
    }
    return proceed;
}

当Mono或Flux时如何从joinPoint.proceed()返回的对象?

谢谢。

2 个答案:

答案 0 :(得分:0)

您可以这样做,继续操作时返回单声道

@Around("somePointCut()")
public Object aspectForSomething(ProceedingJoinPoint point) throws Throwable {
    Flux flux = (Flux) point.proceed();
    return flux
            .doOnNext(obj -> {
                log.error("just take a look: " + obj);
            })
            .map(obj -> {
                if (obj instanceof SomeBo) {
                    SomeBo bo = (SomeBo) obj;
                    bo.setName("do some modification");
                    return bo;
                } else {
                    return obj;
                }
            });
}

答案 1 :(得分:0)

关键是将joinPoint.proceed()包装在Mono中,并在反应链中进行访问。

@Around("@annotation(simpleEvent)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint, SimpleEvent simpleEvent) throws Throwable {
    final long start = System.currentTimeMillis();
    Mono proceed = null;
    try {
        proceed = (Mono) joinPoint.proceed();

        return proceed.doOnNext(response -> {
            final long executionTime = System.currentTimeMillis() - start;
            // here you can access the response object and do your actions
            System.out.println(response);
            System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
        });
    } catch (Exception e) {
        e.printStackTrace();
    }
    return proceed;
}