首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

RequestContextHolder.getRequestAttributes()在@Async之后获取null

RequestContextHolder.getRequestAttributes()在@Async之后获取null的原因是因为@Async注解会开启一个新的线程来执行被注解的方法,而RequestContextHolder.getRequestAttributes()方法是通过ThreadLocal来获取当前线程的请求属性,由于新线程没有继承父线程的ThreadLocal变量,所以在新线程中调用该方法会返回null。

解决这个问题的方法是使用CompletableFuture或者自定义的ThreadLocal来传递请求属性。具体步骤如下:

  1. 在异步方法中,将需要的请求属性保存到一个自定义的ThreadLocal变量中,例如:
代码语言:txt
复制
ThreadLocal<ServletRequestAttributes> requestAttributesHolder = new ThreadLocal<>();
requestAttributesHolder.set((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
  1. 在异步方法中,使用CompletableFuture来包装异步任务,并在异步任务中获取保存在ThreadLocal中的请求属性,例如:
代码语言:txt
复制
CompletableFuture.supplyAsync(() -> {
    // 在异步任务中获取请求属性
    ServletRequestAttributes requestAttributes = requestAttributesHolder.get();
    // 执行异步任务的逻辑
    // ...
    return result;
});

通过这种方式,可以在异步任务中获取到正确的请求属性。

需要注意的是,使用自定义的ThreadLocal需要在异步任务执行完毕后手动清除ThreadLocal中的值,以避免内存泄漏。可以在异步任务执行完毕后,添加清除ThreadLocal的代码,例如:

代码语言:txt
复制
CompletableFuture.supplyAsync(() -> {
    // 在异步任务中获取请求属性
    ServletRequestAttributes requestAttributes = requestAttributesHolder.get();
    // 执行异步任务的逻辑
    // ...
    return result;
}).whenComplete((result, throwable) -> {
    // 异步任务执行完毕后清除ThreadLocal
    requestAttributesHolder.remove();
});

这样就可以解决在@Async之后调用RequestContextHolder.getRequestAttributes()获取null的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

没有搜到相关的合辑

领券