我们正在将旧的Spring应用程序迁移到spring boot 2.0。
目前我们有一个拦截器,它在链中首先执行并执行以下操作:
ThreadLocal
中设置唯一ID我试图找到一种方法在Spring WebFlux中实现它。我能够使用WebFilter
实现它;但是,因为我使用RouterFunction
作为控制器,我试图检查是否有办法通过HandlerFilterFunction
实现这一目标。
public class TxIdFilter implements HandlerFilterFunction<ServerResponse, ServerResponse> {
/**
* {@inheritDoc}
*/
@Override
public Mono<ServerResponse> filter(ServerRequest request, HandlerFunction<ServerResponse> next) {
/*
* How to achieve following (which can be done
* using WebFilter)
*
* exchange.getResponse().beforeCommit(() -> {
* logger.debug("Cleaning up the tx id...");
* AppTransactionContext.removeAll();
* return Mono.empty();
* });
*/
return next.handle(request);
}
}
这是你如何做到这一点,虽然我在这里使用请求属性:
public class SampleFilterFunction implements HandlerFilterFunction {
@Override
public Mono filter(ServerRequest request, HandlerFunction next) {
request.attributes().put("key", "value");
return next.handle(request)
.doOnSuccessOrError((value, error) -> request.attributes().remove("key"));
}
}
你不应该在这里依赖ThreadLocal
,因为与Servlet Spring MVC模型不同,请求不依赖于特定的线程。请求处理可以在任何给定时间跳转到不同的线程。
Reactor provides a Context
API for those uses cases。
根据您的实际用例(我不确定此事务ID在此处可能含义),您还可以查看Spring Cloud Sleuth和Micrometer以及它们如何在各自的用例中解决该问题。