beanManager.getReference() 是线程安全的吗?
Is beanManager.getReference() thread-safe?
我有 class 标有@Singleton。
要获取 class 的实例,我使用以下代码:
public Object getMySingleton(Class someClass){
Bean bean = (Bean) beanManager.getBeans(someClass).iterator().next();
CreationalContext ctx = beanManager.createCreationalContext(bean);
Object obj =beanManager.getReference(bean, someClass, ctx);
return obj;
}
请注意 getMySingleton 不是 synchronized
。这段代码是线程安全的吗?我的意思是,可以从不同的线程调用 getMySingleton - 我会在所有调用者中获得相同的 Singleton 实例吗?
作为 javaee 服务器,我使用 glassfish 和 weld 作为 cdi 容器。但是,我想根据 java-ee 规范得到共同的答案。
是的,是的。
getReference()
实际上是 returns 一个 proxy 实例,后者又委托给实际实例。对于虚构的 SomeBean
class:
大致看起来像这样
public SomeBeanCDIProxy extends SomeBean implements Serializable {
public String getSomeProperty() {
SomeBean instance = CDI.resolveItSomehow();
return instance.getSomeProperty();
}
public void setSomeProperty(String someProperty) {
SomeBean instance = CDI.resolveItSomehow();
instance.setSomeProperty(someProperty);
}
}
实际实例不一定在创建和返回代理实例时创建和可用。只有当您在代理上调用其中一个 bean 方法,并且实际实例在其范围内不可用时,CDI 才会创建实际实例并将方法调用委托给它。无论您以何种方式获取代理(手动或注入),实际实例在逻辑上都是以线程安全的方式创建的。否则它也无法用于注射。
我有 class 标有@Singleton。
要获取 class 的实例,我使用以下代码:
public Object getMySingleton(Class someClass){
Bean bean = (Bean) beanManager.getBeans(someClass).iterator().next();
CreationalContext ctx = beanManager.createCreationalContext(bean);
Object obj =beanManager.getReference(bean, someClass, ctx);
return obj;
}
请注意 getMySingleton 不是 synchronized
。这段代码是线程安全的吗?我的意思是,可以从不同的线程调用 getMySingleton - 我会在所有调用者中获得相同的 Singleton 实例吗?
作为 javaee 服务器,我使用 glassfish 和 weld 作为 cdi 容器。但是,我想根据 java-ee 规范得到共同的答案。
是的,是的。
getReference()
实际上是 returns 一个 proxy 实例,后者又委托给实际实例。对于虚构的 SomeBean
class:
public SomeBeanCDIProxy extends SomeBean implements Serializable {
public String getSomeProperty() {
SomeBean instance = CDI.resolveItSomehow();
return instance.getSomeProperty();
}
public void setSomeProperty(String someProperty) {
SomeBean instance = CDI.resolveItSomehow();
instance.setSomeProperty(someProperty);
}
}
实际实例不一定在创建和返回代理实例时创建和可用。只有当您在代理上调用其中一个 bean 方法,并且实际实例在其范围内不可用时,CDI 才会创建实际实例并将方法调用委托给它。无论您以何种方式获取代理(手动或注入),实际实例在逻辑上都是以线程安全的方式创建的。否则它也无法用于注射。