我认为您不需要自己
ThreadLocal就可以使用请求属性。
@Overridepublic Object afterBodyRead( Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { var common = ((MyGenericPojo) body).getCommon(); if (common.getRequestId() == null) { common.setRequestId(generateNewRequestId()); } Optional.ofNullable((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .map(ServletRequestAttributes::getRequest) .ifPresent(request -> {request.setAttribute(Common.class.getName(), common);}); return body;}@Overridepublic MyGenericPojo beforeBodyWrite( MyGenericPojo body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { Optional.ofNullable(RequestContextHolder.getRequestAttributes()) .map(rc -> rc.getAttribute(Common.class.getName(), RequestAttributes.SCOPE_REQUEST)) .ifPresent(o -> { Common common = (Common) o; body.setCommon(common); }); return body;}编辑
Optional可以替换为
RequestContextHolder.getRequestAttributes().setAttribute(Common.class.getName(),common,RequestAttributes.SCOPE_REQUEST);RequestContextHolder.getRequestAttributes().getAttribute(Common.class.getName(),RequestAttributes.SCOPE_REQUEST);
编辑2
关于线程安全
1)我们基于标准的基于servlet的Spring
Web应用程序提供了每个请求线程的场景。工作线程之一通过所有筛选器和例程处理请求。处理链将从头到尾由相同的线程执行。因此,
afterBodyRead并
beforeBodyWrite保证由给定请求的同一线程执行。
2)您的RequestResponseAdvice本身是无状态的。我们使用了
RequestContextHolder.getRequestAttributes()ThreadLocal并声明为
private static final ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal<>("Request attributes");ThreadLocal javadoc指出:
他的课提供了线程局部变量。这些变量与普通变量不同,因为每个访问一个线程(通过其get或set方法)的线程都有其自己的,独立初始化的变量副本。
因此,我没有在此支持中看到任何线程安全问题。



