【问题标题】:How do you create a non-Thread-based Guice custom Scope?如何创建非基于线程的 Guice 自定义 Scope?
【发布时间】:2010-03-23 18:49:02
【问题描述】:

似乎所有 Guice 开箱即用的 Scope 实现本质上都是基于线程的(或完全忽略线程):

Scopes.SINGLETONScopes.NO_SCOPE 忽略线程并且是边缘情况:全局范围和无范围。

ServletScopes.REQUESTServletScopes.SESSION 最终依赖于从ThreadLocal<Context> 检索作用域对象。检索到的Context 包含对HttpServletRequest 的引用,HttpServletRequest 包含对存储为命名属性的作用域对象的引用(其中名称派生自com.google.inject.Key)。

来自自定义范围 Guice wiki 的类 SimpleScope 还提供了使用 ThreadLocal<Map<Key<?>, Object>> 成员变量的每线程实现。

有了前言,我的问题是:如何创建一个非基于线程的作用域?我可以用来查找Map<Key<?>, Object> 的东西似乎丢失了,因为传递给Scope.scope() 的唯一东西是Key<T>Provider<T>

提前感谢您的宝贵时间。

【问题讨论】:

  • 如果您解释您希望 Scope 如何决定它应该创建一个新对象还是重用现有对象,这可能会有所帮助。另一种看待它的方式是您希望对象的生命周期是什么。

标签: scope guice


【解决方案1】:

有点不清楚您想要什么 - 您不想要基于线程的范围,也不想要忽略线程的范围。

但是,是的,作用域旨在管理对象的生命周期,并说明何时应重用实例。所以你真的在问“除了‘总是使用同一个实例’、‘从不使用同一个实例’和‘根据当前线程的执行环境使用一个实例’之外,还有什么其他的可能性可以重用一个实例? ?”

下面是我想到的:

  • 在固定时间内使用同一实例。此处的示例是每十分钟重新加载和重新解析的配置文件。
  • 执行一些网络调用来查询给定的对象是否应该被重用(也许这是一个快速调用来确定我们是否需要重建对象,但重建对象的调用很慢)
  • 重复使用同一个对象,直到有外部调用告诉我们重新加载
  • 在每个线程中重复使用相同的对象,但不像 servlet 范围那样使用显式输入和离开的范围。 (所以每个线程一个实例)
  • 基于InheritableThreadLocal 而非普通ThreadLocal 的“此线程和子线程”范围。
  • 与此相关,Scope 和基于线程池的ExecutorService 一起工作,以便在线程和它提交以供后台执行的作业之间共享实例。
  • 从池中拉出实例;这很棘手,因为我们需要一种在完成后将对象返回到池中的好方法。 (也许您可以将此想法与请求范围之类的东西结合起来,以便在请求结束时将对象返回到池中)
  • 由两个或多个其他范围组成的范围,例如,我们可以获得一个配置对象,该对象每 10 分钟重新读取一次,除非在给定请求的整个生命周期中使用相同的实例。

【讨论】:

  • 这都是值得深思的好东西。最后,我决定根本不需要 Scope。我只需要正确声明绑定注释,使用私有模块,并且只公开我想要的那些绑定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多