我们正在将旧的Spring应用程序迁移到spring boot 2.0。
目前我们有一个拦截器,它在链中首先执行并执行以下操作:
ThreadLocal
我试图想出一种在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);
}
}
答案 0 :(得分:1)
以下是您可以这样做的方法,虽然我在这里使用的是请求属性:
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以及他们如何解决问题各自的用例。