如何使用 Guice 控制对象的生命周期

发布于 2024-11-17 08:49:56 字数 293 浏览 2 评论 0原文

我有 Guice 注入的对象,它有两个生命周期方法 bind()unbind()。 Guice 使用以下带注释的方法实例化对象后,会自动调用方法 bind()

@Inject
final void autoBind() {
    bind();
}

我想要做的是在旧的对象上调用方法 unbind() Guice 创建对象的新实例之前的(当前)对象。我该怎么做?

提前致谢!

I have Guice-injected objects which have two lifecycle methods bind() and unbind(). The method bind() is called automatically after the object is instantiated by Guice using following annotated method:

@Inject
final void autoBind() {
    bind();
}

What I want to do is to call the method unbind() on the old (current) object before a new instance of the object is created by Guice. How do I do that?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱给你人给你 2024-11-24 08:49:56

首先,我不建议您只使用@Inject注释任意方法。将其保留给构造函数,偶尔用于可选的注入和/或字段注入。

你想做的事情听起来有点奇怪,我不确定这是否正是你想要的。您能否提供更多有关您正在尝试做的事情的背景信息,因为也许不同的方法更好。这里肯定存在一些关于线程安全以及如何管理引用的问题。

根据您的描述,@meverett 提到的方法可能会起作用。如果您拥有的对象是 Foo,它看起来会像这样。

// Later on be sure to bind(Foo.class).toProvider(FooProvider.class);
final class FooProvider implements Provider<Foo> {
  private final Provider<Foo> unboundFooProvider;

  private Foo currentInstance;

  @Inject FooProvider(@Unbound Provider<Foo> unboundFooProvider) {
    this.unboundFooProvider = unboundFooProvider;
  }

  @Override public Foo get() {
    if (currentInstance != null) {
      currentInstance.unbind();
    }
    currentInstance = unboundFooProvider.get();
    currentInstance.bind();
    return currentInstance;
  }
}

请注意,您的 @Unbound Foo 提供程序将生成 Foo 而无需调用任何特殊方法。常规的 FooProvider 会跟踪状态并决定何时 bind()unbind() 实例。请小心管理多个实例并将其与多个线程一起使用的方式。

另外,需要明确的是:我使用 @Unbound 因为您要调用的方法称为 bind()unbind() 。我没有使用 Guice 意义上的“绑定”。

另请注意...我非常确定提供者被视为单例,因此像这样维护状态是可行的。如果没有,您显然可以使用某种单例工厂创建一个间接级别(但这不是必需的)。

First of all, I would not advise that you just annotate arbitrary methods with @Inject. Keep it to constructors, and occasionally for optional injection and/or field injection.

What you are trying to do does sound a bit weird, and I'm not sure it's exactly what you want. Can you please provide more background on what you're trying to do because maybe a different approach is better. There are definitely some concerns here with thread safety and how you manage references.

Based on what you described, an approach like what @meverett mentioned would probably work. If the objects you have are Foos, it would look something like this.

// Later on be sure to bind(Foo.class).toProvider(FooProvider.class);
final class FooProvider implements Provider<Foo> {
  private final Provider<Foo> unboundFooProvider;

  private Foo currentInstance;

  @Inject FooProvider(@Unbound Provider<Foo> unboundFooProvider) {
    this.unboundFooProvider = unboundFooProvider;
  }

  @Override public Foo get() {
    if (currentInstance != null) {
      currentInstance.unbind();
    }
    currentInstance = unboundFooProvider.get();
    currentInstance.bind();
    return currentInstance;
  }
}

NOTE that your @Unbound Foo provider would generate Foos without invoking any special methods. The regular FooProvider keeps track of state and deciding when to bind() and unbind() the instances. Please be careful with how you manage multiple instances and use them with multiple threads.

Also, just to be clear: I'm using @Unbound since the methods you want to invoke are called bind() and unbind(). I'm not using "bound" in the Guice sense.

Also note... off the top of my head I'm pretty sure Providers are treated as singletons, so maintaining state like this will work. If it didn't, you could obviously just create a level of indirection with some kind of singleton factory (but that shouldn't be necessary).

小…楫夜泊 2024-11-24 08:49:56

之前的回复很好地解决了其他问题,所以只回答这个问题:

Netflix 在 2012 年引入了 github 中的州长,以“ 增强 Google Guice 提供 ... 生命周期管理"。它提供注释(@PreConfiguration@PostConstruct@PreDestroy 等)、类路径扫描和注释。自动绑定等功能。 Bootstrapping 非常简单。

Previous responses address other concerns nicely, so to just answer the question:

Netflix introduced governator in github in 2012 to "enhance Google Guice to provide ... lifecycle management". It provides annotations (@PreConfiguration, @PostConstruct, @PreDestroy, and others), classpath scanning & auto binding, and other features. Bootstrapping is straight forward.

傾旎 2024-11-24 08:49:56

我想你可以有一个提供者来保存对当前对象的引用。当您在提供者上调用 get 时,它将取消绑定最后一个对象,构造新对象并保存对其的引用。

虽然我不太确定为什么你会想要做这样的事情,因为理论上其他对象仍然可以引用它

I suppose you could have a provider that keeps a reference to the current object. When you call get on the provider it would unbind the last object, construct the new one and save the reference to it.

though I'm not really sure why you would want to do something like this since other objects can in theory still be referencing it

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文