【问题标题】:CDI choosing correct scope for beanCDI 为 bean 选择正确的范围
【发布时间】:2012-10-18 22:16:15
【问题描述】:

来自 Spring 的普通旧 DI,在使用 CDI 编写时,我无法弄清楚如何正确选择范围。

在 Spring 中,默认情况下我的所有服务都具有单例范围,我想它映射到 CDI 中的应用程序范围(甚至是 @Singleton)。我知道例如登录用户信息我需要使用会话范围,例如表单参数我需要请求范围。

假设我有一个隐藏外部服务 API 调用的 bean。它是完全无国籍的。我应该把它写成@Singleton 还是只是应用程序范围?或者让它在每个请求上创建(可能是错误的选择)。

到处注入所有东西是否正确?在 Spring 中,我通过 new 创建我的数据对象。我应该在 CDI 中做同样的事情,还是干脆 @Inject 他们?

【问题讨论】:

    标签: java jakarta-ee dependency-injection java-ee-6 cdi


    【解决方案1】:

    您只使用 CDI 吗?还是 Java EE 6 容器?如果您有一个用于服务调用的无状态类,那么我建议您使用来自 EJB 规范的 @Stateless(因此您需要一个 Java EE 6 容器)它不是单例,但它不是也可以在每个请求上创建。我相信它与会话的绑定更紧密,但由于它是无状态的,因此可以将实例池化和共享。如果您只处理 CDI,我相信 Singleton 更直接地匹配 Spring 的单例,但我建议使用 ApplicationScoped,因为它提供了一个代理,使得使用它的 bean 的序列化更容易。

    【讨论】:

    • 谢谢,我正在使用 JEE 应用服务器。是的,我可以使用 Stateless,这是真的。
    • 在 Weld 和 OWB 中(不确定 CanDI)@Singleton@ApplicationScoped 实际上是相同的。
    【解决方案2】:
    @Service
    @Scope("prototype")
    public class CustomerService 
    {
    ......
    }
    

    只需将 @Scope("prototype") 注释添加到您的组件。

    【讨论】:

      【解决方案3】:

      是否有理由需要 bean 记住它的状态?如果您使用的是 Web 客户端之类的东西,那么这是一个更好的存储状态的地方,比如会话范围的托管 bean(假设为 jsf),或者任何适合您的情况的等价物。在后端服务器端,您的 EJB 最好保留为 @stateless,以将开销降至最低,并有助于“保持简单...”范式。如果这可行,只需在您的 bean 上声明 @Stateless。除非有理由使用单例,否则如果您想为您的服务使用 Java EE 容器,最好还是使用无状态 bean。

      无状态 bean 并没有真正随着每个请求而重新创建。这就是游泳池的目的。应用服务器手头有现成的无状态 bean,如果它忙,它会制造更多,如果它安静下来,它会清空一些。

      【讨论】:

        猜你喜欢
        • 2012-01-20
        • 1970-01-01
        • 1970-01-01
        • 2021-08-18
        • 1970-01-01
        • 2014-07-17
        • 2015-08-23
        • 2013-11-06
        相关资源
        最近更新 更多