【问题标题】:Proper Scopehandling in GUICE @Singleton vs. Default ScopeGUICE @Singleton 中的正确作用域处理与默认作用域
【发布时间】:2014-12-03 12:33:15
【问题描述】:

已经在 (https://groups.google.com/forum/#!searchin/google-guice/Should$20Guice-Injected$20DAO$27s$20be$20Singletons$3F/google-guice/3B8XrwB-p18/B6OF13HWRnEJ) 提出了类似的问题,但我认为它没有收到一个令人满意的答案。

基线: 我们在 Tomcat 上运行的 JSF/Primefaces Web 应用程序中使用 Guice。持久性是通过 JPA/Hibernate 处理的。

现在我们所有的 DAO(每个实体大约一个)都被注释为 @Singleton。造成这种情况的唯一原因似乎是性能问题,因为应用程序的另一个(非 JSF,而是 Web 服务)部分每秒会收到数千次点击,我们的主要开发人员认为,构建一次 DAO 单例然后以同步方式获取它是比总是注入一个新实例(这是 Guice 默认范围)便宜。 这与 Google Guice Wiki 关于 Scopes 的描述背道而驰:如果对象是无状态的且创建成本低廉,则无需进行范围界定。让绑定不受范围限制,Guice 将根据需要创建新实例……虽然单例保存对象创建(以及以后的垃圾收集),但单例的初始化需要同步; ...

现在,在这种情况下,“单例的初始化”到底是什么意思?初始化是否完成一次?每次都注射?

在上述场景(每秒数千次点击)中,使用 @Singleton 注释的 DAO 比使用 Default Scope 更快、更节省资源的假设是否正确?

当我们为 DAO 使用 @Singleton 时,我们不会直接注入 EntityManager,而是使用 EntityManagerProvider,据我了解,这是正确的方法,因为 Provider 被认为是线程安全的,这是 @Singleton 的要求。 是否有“Google 认可”的方式在您的 Web 应用程序中使用 DAO 包含 Hibernate?

【问题讨论】:

  • 我相信 Leave the binding unscoped and Guice will create new instances as they're required... 评论是为了防止开发人员混合范围。您能否添加有关您的 EntitiyManager 范围的更多信息?您如何处理 EM 上下文的打开和关闭?就个人而言,我认为Singleton 已经到位并且性能会更好,因为在 GC 和初始化方面很少。无论如何,您必须知道如何将注入与不同的范围混合并注入EntityManager 作为提供者,您做了什么,所以您准备好了,gj。
  • > 你能添加更多关于你的 EntityManager 范围的信息吗? EntityManager 范围是什么意思?您如何处理 EM 上下文的打开和关闭? --- 现在我们正在使用 guice-persist 的 @Transactional 注释,但当我了解到它不再维护时,我们可能会切换到 onami-persist。
  • 您从哪里得知guice-persist 不再维护?它似乎有最近的提交。
  • 最后一个非 Beta 版本是从 2011 年 3 月 24 日开始的。这里还有 scl 的回答:groups.google.com/forum/#!topic/google-guice/y2N1PSNmhGk
  • @MichaelFrank Guice 的最后一个非 beta 版本是在 2011 年 3 月 24 日。

标签: java scope singleton guice


【解决方案1】:

虽然单例可以节省对象的创建(以及后来的垃圾 collection),单例的初始化需要同步; ...

现在,“单例的初始化”到底是什么意思 语境?初始化是否完成一次?每次都注射?

Here 是单例作用域的实现(在 Guice 的发布版本中略有不同,但以下几点仍然成立)。每次在任何地方注入单例范围的依赖项时,都会调用该提供程序上的 get() 方法来获取实例。

使用双重检查锁定,以便在第一次创建单例后,将来对 get() 的调用很便宜:它们读取单个 volatile 字段并返回。

另一方面,使用@Singleton DAO 意味着您必须在每个方法中通过Provider 访问EntityManager,这包括在HashMap 中查找EntityManager 在某处的ThreadLocal .

结论:找到哪种选择对性能更好的唯一方法是对两者进行基准测试并选择速度更快的选择。您可能会发现这两种选择都足够快,在这种情况下,您应该选择最干净的一种。

【讨论】:

  • 我做了一些(非详尽的)性能测试,无法测量 Singleton 和默认 Scope 之间的任何显着差异,即使在使用 100k+ 请求触发垃圾收集运行等进行测试之后也是如此。所以,我我会接受你的回答,因为它并没有真正回答我的问题,但无论如何它是最有用的(尤其是关于双重检查锁定的信息)。尽管如此,我还是觉得奇怪的是,Google Dev 没有关于此的适当信息,Google 开发人员在 google guice 邮件列表上没有任何答案,并且一些教程坚持使用 Singleton Scope。
猜你喜欢
  • 2018-05-31
  • 1970-01-01
  • 1970-01-01
  • 2013-05-30
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 2013-12-25
  • 2019-06-03
相关资源
最近更新 更多