详解详解Spring框架下向异步线程传递框架下向异步线程传递HttpServletRequest参数的参数的
坑坑
主要介绍了详解Spring框架下向异步线程传递HttpServletRequest参数的坑,小编觉得挺不错的,现在分享给大
家,也给大家做个参考。一起跟随小编过来看看吧
在spring的注解 @RequestMapping 之下可以直接获取 HttpServletRequest 来获得诸如request header等重要的请求信息:
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
private static final String HEADER = "app-version";
@RequestMapping(value = "/async", method = RequestMethod.GET)
public void test(HttpServletRequest request) {
request.getHeader(HEADER);
}
}
往往,这些重要的信息也会在异步线程中被使用到。于是,一个很自然的想法是,那不如直接把这里获取到的request当做参
数传到其它spawn出的子线程里,比如:
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
private static final String HEADER = "app-version";
@RequestMapping(value = "/async", method = RequestMethod.GET)
public void test(HttpServletRequest request) {
log.info("Main thread: " + request.getHeader(HEADER));
new Thread(() -> {
log.info("Child thread: " + request.getHeader(HEADER));
}).start();
}
}
在header中设置"app-version"为1.0.1后发送 <base_url>/test/async 请求,可以看到结果:
Main thread: 1.0.1
Child thread: 1.0.1
但是,坑,也就此出现了。
由于 HttpServletRequest 不是线程安全的(后知后觉),当主线程完成自己的工作返回response后,相应的诸如
HttpServletRequest 等对象就会被销毁。为了看到这个现象,我们可以在子线程中多等待一段时间来保证主线程先于子线程结
束。
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
private static final String HEADER = "app-version";
private static final long CHILD_THREAD_WAIT_TIME = 5000;
@RequestMapping(value = "/async", method = RequestMethod.GET)
public void test(HttpServletRequest request) {
log.info("Main thread: " + request.getHeader(HEADER));
new Thread(() -> {
try {
Thread.sleep(CHILD_THREAD_WAIT_TIME);
} catch (Throwable e) {
}
log.info("Child thread: " + request.getHeader(HEADER));
}).start();
}
}
评论0
最新资源