【问题标题】:Optional injection in GuiceGuice 中的可选注入
【发布时间】:2015-03-19 23:08:11
【问题描述】:

是否可以告诉 Guice 不需要注入所有构造函数参数?例如,我有一个构造函数Foo,它接受BarBaz 类型的两个参数。在我的系统中,它们都是可选的:它们可能

  1. 两者都在场
  2. 都不见了
  3. 只有Bar 在场
  4. 只有Baz 在场。

也就是说,它依赖于提供这些绑定的其他模块。我想得到这样的东西:

class Foo {
  private final Bar bar;
  private final Baz baz;

  @Inject(optional = true)
  public Foo(@Nullable Bar bar, @Nullable Baz baz) {
    this.bar = bar;
    this.baz = baz;
  }
}

但我不能真正将optional 与构造函数一起使用。有没有办法做到这一点?

【问题讨论】:

  • 默认值是多少?按照惯例,可选依赖项使用 setter 而不是构造函数参数来表示。
  • 默认 null 对我来说很好。所以我应该让构造函数为空并使用setter?

标签: java guice


【解决方案1】:

我认为preferred Guice pattern 是:

public class HolderPatter {

  static class Bar {
    @Inject Bar(BarDependency dependency) {}
  }
  static class Baz {
    @Inject Baz(BazDependency dependency) {}
  }

  static class BarHolder {
    @Inject(optional=true) Bar value = null;
  }

  static class BazHolder {
    @Inject(optional=true) Baz value = null;
  }

  static class Foo {
    private final Bar bar;
    private final Baz baz;

    @Inject
    public Foo(BarHolder bar, BazHolder baz) {
      this.bar = bar.value;
      this.baz = baz.value;
    }
  }
}

请注意,这也将允许您指定合理的默认值...

【讨论】:

  • 太棒了!非常感谢!
  • Guice 在启动时仍然失败,因为它找不到 Baz 的绑定。有没有办法避免这种情况?
  • 奇怪 - optional=true 它适用于我并使用默认的空值。你也在其他地方注射 Baz 吗?
【解决方案2】:

Guice 的最新版本最近添加了OptionalBinder,它比@Inject(optional=true) 方法效果更好,还添加了一些高级功能。

另请参阅thread where OptionalBinder was announced

【讨论】:

  • 值得注意的是,这比使用@Inject(optional=true) 进行字段注入需要更多的仪式,并且更适合图书馆作者。
猜你喜欢
  • 2011-06-07
  • 2021-03-04
  • 1970-01-01
  • 2012-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多