【问题标题】:Lifetime management with Google Guice使用 Google Guice 进行生命周期管理
【发布时间】:2009-11-04 14:49:04
【问题描述】:

是否有关闭/关闭使用 Guice 创建的对象的推荐模式?

我的目标生命周期是:

  1. 准备一个 Guice 模块
  2. 创建注入器
  3. 通过代码使用注入器获取对象 (injector.getInstance(Foo.class))
  4. ...
  5. 关闭上述对象持有的所有资源(文件句柄、TCP 连接等...)。我希望这是一个确定性步骤(而不是“GC 运行的某一天”)。

【问题讨论】:

  • 您可能想在您的问题中添加一些示例代码,因为我不太明白您的意思。
  • “通过您的代码使用注入器来获取对象 (injector.getInstance(Foo.class))” - 这显然 不是 Guice 或任何 DI 的意图要使用的。那只是一个服务定位器。它应该正在构建您的对象图,并且注入器应该只在某些根引导程序类中创建和引用。
  • 是的,这就是我评论而不是回复的原因。我认为您可能想要使用 injector.getInstance(Foo.class) 的任何地方都应该能够注入 Provider 并使用它来代替。
  • 但是该类清楚地声明了它所依赖的内容,而当您看到一个引用了注入器的类时,您不知道它可能会从那里得到什么。是的,这对于单元测试有很大的不同......不必配置注入器,只需制作一个假提供者,它可以返回您想要的实例。您不再依赖于提供依赖项的机制......只依赖于依赖项本身。
  • 这些cmets是在浪费时间!好问题!

标签: java dependency-injection guice object-lifetime


【解决方案1】:

我希望这是一个确定性步骤(而不是“GC 运行的某一天”)。

抱歉,Java 对您来说是错误的语言。 DI 框架不知道对象的所有引用何时都消失了。只有 GC 知道这一点。

如果您有“可关闭”资源,则使用 try/finally 模式将其关闭(见下文)。

Closable c = // ...
try {
   c.use();
} finally {
   c.close();
}

现在退后一点。 Guice 可以知道作用域的开始和结束时间。您的自定义范围可以在完成后运行清理步骤。此范围甚至可以返回代理,因此如果您尝试在允许范围之外访问它们,这些对象将无效。

(哦,对 ColinD +1 - 注入提供程序。:)

编辑Guiceyfruit 接缝以支持Lifecycles

【讨论】:

  • 我认为这只是对 GC 用途的经典误解(如果您使用 C++ 编程,则特别容易犯此错误)。在垃圾回收语言中,对象生命周期/GC 与释放文件句柄或网络套接字等资源无关。
  • 代码块不分配对象,所以不负责释放。具体来说,单例(在 Guice 模块中)由 Injector.getInstance() 获得,但在使用后不应关闭。
  • 这整个问题很大程度上取决于您正在做什么以及在什么环境中。不同的对象有不同的生命周期、不同的范围等,因此没有万能的简单解决方案。您是在 web 应用程序中执行此操作吗?您主要是在谈论关闭时关闭单例吗?
  • 单例只能在应用程序关闭期间“释放”(因此通过关闭挂钩)。我相信您可以编写一个处理该问题的范围。
  • 另外,如果代码块从提供者那里检索到一个无作用域的对象并使用它,它肯定会负责在必要时关闭该对象,尽管它本身没有创建。
猜你喜欢
  • 1970-01-01
  • 2010-10-16
  • 2012-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多