1.啥也不说先上代码
2.我们来探究下这两行代码能实现属性共享的原理,其中的关键就是RequestContextHolder类
3.RequestContextHolder类字面解释就是以线程绑定的的形式保存web请求的相关信息的holder类,通过设置inheritable属性来决定是否能被子线程继承;该类里面包含两个ThreadLocal全局属性
4.其中的inheritableRequestAttributesHolder 存储的request属性就表示运行子线程去继承的,第一个步骤的 RequestContextHolder.setRequestAttributes(attributes,true) 就是把request的属性放入到inheritableRequestAttributesHolder 中
5.子线程具体是如期去获取主线程的request的属性的呢,请看下图,子线程中 requestAttributesHolder.get() 获取属性为空,就会从inheritableRequestAttributesHolder 中去获取属性了
6.还有个问题那3步骤中的 requestAttributesHolder 属性是在什么时候放进去的呢,从类的说明中看看到 DispatcherServlet 类已经默认把web request的属性放到了 requestAttributesHolder 中,DispatcherServlet 继承自 FrameworkServlet,在FrameworkServlet的processRequest()方法中的resetContextHolders会把web request的属性放入到requestAttributesHolder 中,具体请看下图
7.自此异步子线程共享主线程request属性的源码剖析已经结束。需要说明的是这种共享方式适合用于主线程等待子线程完成任务后在结束的情况,否则主线程调用主线程先与子线程结束的话主线程的request 会被销毁,子线程还是共享不了主线程的request属性。针对后面的情况又是另外的解决方案了。
网友评论