基于直觉的答案
我相信它是线程安全的,因为请求范围是线程安全的(会话及以上不是,因为用户可以打开多个浏览器会话并使用相同的会话 ID)
我测试了它,虽然它是经验证据,但注入HttpRequestProducer
的每个请求都会获得一个新实例。
请注意,requestInitialized
andrequestDestroyed
可以是(实际上是)不同的线程,因此如果您打算在两种方法上使用相同的注入对象,我将进一步调查。
规格支持的答案
困难的部分是在规格中为这种说法找到确凿的证据。
我查看了 CDI 规范,并不能很快找到确凿的证据证明 @RequestScoped 对象是线程安全的(例如,使用线程本地)但是我假设 @RequestScoped bean 使用与 Java EE 5 中的作用域 bean 相同的作用域: (见这里)
在那里,这个条款很有趣:
控制对共享资源的并发访问 在多线程服务器中,可以同时访问共享资源。除了范围对象属性之外,共享资源还包括内存中的数据(例如实例或类变量)和外部对象,例如文件、数据库连接和网络连接。
并发访问可能在以下几种情况下出现:
多个 Web 组件访问存储在 Web 上下文中的对象。
多个 Web 组件访问存储在会话中的对象。
Web 组件中的多个线程访问实例变量。Web 容器通常会创建一个线程来处理每个请求。如果要确保 servlet 实例一次只处理一个请求,则 servlet 可以实现 SingleThreadModel 接口。如果一个 servlet 实现了这个接口,就可以保证在 servlet 的 service 方法中不会有两个线程同时执行。Web 容器可以通过同步对 servlet 的单个实例的访问,或通过维护 Web 组件实例池并将每个新请求分派到空闲实例来实现此保证。此接口不能防止由于 Web 组件访问共享资源(例如静态类变量或外部对象)而导致的同步问题。此外,Servlet 2.
所以从理论上讲,似乎对象本身每个请求线程都会有一个实例,但是我找不到任何确凿的证据证明这一点是受支持的。