主线程新开一个子线程,子线程能获取request信息吗?

不能,解决办法在开启子线程前加入以下代码:

  1. ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
  2. RequestContextHolder.setRequestAttributes(attributes, true);

image.png
探究下这两行代码能实现属性共享的原理,关键就是RequestContextHolder类,该类的源码注释为:

Holder类以线程绑定的形式公开Web请求对象。 该请求将被继承由当前线程产生的任何子线程(如果{Inheritable}标志设置为{true}。

image.png
该类里面包含两个ThreadLocal全局属性,其中的inheritableRequestAttributesHolder 存储的request属性就表示运行子线程去继承的,第一个步骤的 RequestContextHolder.setRequestAttributes(attributes,true) 就是把request的属性放入到inheritableRequestAttributesHolder 中。

image.png
获取属性方法如上图。

还有一个问题,requestAttributesHolder属性是什么时候被写入的?
从类得说明中,DispatcherServlet 类已经默认把web request的属性放到了 requestAttributesHolder 中,DispatcherServlet 继承自 FrameworkServlet,在FrameworkServlet的processRequest()方法中的resetContextHolders会把web request的属性放入到requestAttributesHolder 中,如下所示
image.png