static - @Singleton 与 @ApplicationScope

标签 static singleton synchronized

对于一个项目,我需要一个唯一的 ID 生成器。所以我想到了一个带有同步方法的单例。

由于遵循传统单例模式( private static instance )的单例在跨 session 中共享,我想知道 @Singleton注释的工作方式相同吗?

文档说:Identifies a type that the injector only instantiates once.
这是否意味着 @Singleton根据 User Session 将是独立的(这对 id 生成器不利)?我应该更喜欢 old school单例与 Class.getInstance()通过注入(inject) @Singleton - bean ?

或者我应该既不使用也不应该在 @ApplicationScoped 内提供服务 bean ?

必须保证只有一个独立于用户 session 的线程可以访问生成下一个 id 的方法。 (自动增量数据库 id 无法解决)

编辑:JSF 2.2、CDI 和 javax.inject.*我在说:)

最佳答案

所有这些类型的单例( static@javax.inject.Singleton@javax.ejb.Singleton@javax.enterprise.context.ApplicationScoped )被创建 每个 JVM 一次 .
每个用户 session 创建一次的对象必须用 @javax.enterprise.context.SessionScoped 注释。所以不,每个用户 session 都不会实例化单例。
注意有两个 @Singleton注释,javax.inject 中的一个另一个在 javax.ejb包裹。我用它们的完全限定名称来指代它们以避免混淆。
所有这些单例之间的差异都很微妙,我不确定我是否了解所有含义,但我想到了一些:

  • @javax.ejb.Singleton由 EJB 容器管理,因此它可以处理事务(@javax.ejb.TransactionAttribute)、读/写锁定和超时(@javax.ejb.Lock@javax.ejb.AccessTimeout)、应用程序启动(@javax.ejb.Startup@javax.ejb.DependsOn)等.
  • @javax.enterprise.context.ApplicationScoped由 CDI 容器管理,因此您不会拥有 EJB 所具有的事务和锁定功能(除非您使用添加了事务的 1.0 后 CDI),但您仍然有很多不错的东西,例如 @javax.enterprise.inject.Produces , @javax.annotation.PostConstruct , @javax.inject.Named , @javax.enterprise.inject.Disposes (但其中许多特性也可用于 EJB)。
  • @javax.inject.Singleton类似于 @ApplicationScoped ,除了没有代理对象(客户端将直接引用该对象)。到达真实对象的间接性会减少,但这可能会导致一些与序列化相关的问题(参见:http://docs.jboss.org/weld/reference/latest-2.2/en-US/html_single/#_the_singleton_pseudo_scope)
  • 一个普通的静态字段很简单并且可以正常工作,但它由类加载器控制,因此为了了解它们如何/何时被实例化和垃圾收集(如果有的话),您需要了解类加载器如何工作以及您的应用程序服务器如何管理其类加载器(重新启动、重新部署等时)。见 this question更多细节。
  • 关于static - @Singleton 与 @ApplicationScope,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26832051/

    相关文章:

    c - 静态或指针当 "Returning"数组

    c++ - 通过 C++ 中的静态实例的单例——进入源文件或头文件?

    java - synchronized(this) 和类的几个同步方法之间的区别

    java - 为什么要同步Java方法Provider.getService(String type,String algorithm)?

    java - java中 block 2个线程访问一个if block

    c++ - 工作 C++03 代码上的 G++ (C++14) 链接器错误

    rust - 关于Rust静态生命周期和范围的问题

    java - 在 Java Web 应用程序中使用静态方法和变量

    c++ - 为什么 Singleton 是比 Global Objects 更好的选择

    java - spring如何维护单例对象