让我们说我们有一个类:
@RequestScoped
public class FooService {
private NonThreadSafeGenerator generator = new NonThreadSafeGenerator();
public String generateId() {
return this.generator.generateId();
}
}
我们在某些servlet-container下运行应用程序。会是线程安全吗?换句话说,是否可以保证requestScoped的bean总是只能在单程中可见?
是的,可以保证。首先,您可以在6.3普通范围内查看CDI规范。花点时间阅读它,需要一些时间,但得出的结论是,正常范围基本上是线程的。
然后,为了真正说服您,让我们直接看一下WELD代码库。正常范围上下文的所有实现均基于几个抽象的前身类。如果您进行一些挖掘,则可以提出其中两个-AbstractBoundContext
和AbstractUnboundContext
。两者都使用ThreadLocal
来实现基础bean商店 - 这将保证您基于线程的行为。
您的 FooService
bean实例一次仅由一个线程使用。
但是,NonThreadSafeGenerator.generateId()
仍然不安全。例如,它可以依靠状态的静态实例变量,或在其他对象或类上调用一种方法。