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 才会创建实际实例并将方法调用委托给它。无论您以何种方式获取代理(手动或注入),实际实例在逻辑上都是以线程安全的方式创建的。否则它也无法用于注射。