我正在为返回承诺的方法编写方面。考虑以下方法:
public Mono<Stream> publishToKafka(Stream s) {
//publishToKafka is asynchronous
return Mono.just(s).flatMap(worker::publishToKafka);
}
我想缓存发布是否成功。由于这是一个横切关注点,因此方面看起来是最好的设计。这是我的看法。
@Around("@annotation....")
public Object cache() {
//get the data to cache from the annotation
Object result = pjp.proceed();
cache.cache("key","data");
return result;
}
现在自从publishToKafka
是异步的,一旦线程切换发生,目标方法就返回cache.cache()
叫做。这不是我想要的。我想要的是,如果事件已成功发布到 Kafka,则应缓存结果。以下建议有效。
@Around("@annotation....")
public <T extends Stream<T>> Mono<T> cache() {
//get the data to cache from the annotation
return ((Mono<T>)pjp.proceed()).doOnNext(a -> cache.cache(key, data));
}
我想了解这里发生了什么事。这种情况是否发生在管道组装期间?或者在执行期间(pjp.proceed()
返回一个承诺),我的建议添加了doOnNext
操作员?
我需要在这个示例的上下文中了解汇编与执行时间。
Spring AOP 和 AspectJ 方面始终在与拦截的连接点相同的线程中同步执行。因此,如果您拦截的方法立即返回,并且返回值类似于 Promise、Future 或空(void)与回调的组合,则您不能指望在方面的建议中神奇地获得异步结果。您确实需要让方面了解异步情况。
话虽如此,我还想提一下,我以前从未使用过响应式编程,我只知道这个概念。从我在你的建议中看到的,解决方案应该有效,但有一件事不太好:你让建议返回一个new Mono
实例由您返回的doOnNext(..) call https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#doOnNext-java.util.function.Consumer-。也许返回会更干净original Mono
你从proceed()
在注册了缓存回调之后,以避免任何副作用。
我不知道还要解释什么,情况已经很清楚了。如果我的解释还不够,请随时提出直接相关的后续问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)