java - Guice @Provides 方法与提供者类

标签 java dependency-injection guice roboguice

我正在从事一个相当大的项目,其中有很多注入(inject)。我们目前正在使用一个实现 Provider 的类,每个注入(inject)都需要一个,它们大多只有一行 get 方法。

每次我需要一个新的提供者时都需要创建一个新类,这开始变得很烦人。在我的 Module 中使用提供程序类而不是 @Provides 方法有什么好处,反之亦然?

最佳答案

据我所知,对于大多数简单的情况,它们是完全等价的。

/**
 * Class-style provider.
 * In module: bind(Foo.class).annotatedWith(Quux.class).toProvider(MyProvider.class);
 */
class MyProvider implements Provider<Foo> {
  @Inject Dep dep;  // All sorts of injection work, including constructor injection.

  @Override public Foo get() {
    return dep.provisionFoo("bar", "baz");
  }
}

/**
 * Method-style provider. configure() can be empty, but doesn't have to be.
 */
class MyModule extends AbstractModule {
  /** Name doesn't matter. Dep is injected automatically. */
  @Provides @Quux public Foo createFoo(Dep dep) {
    return dep.provisionFoo("bar", "baz");
  }

  @Override public void configure() { /* nothing needed in here */ }
}

在任何一种风格中,Guice 都允许您注入(inject) FooProvider<Foo> ,即使键绑定(bind)到类或实例。 Guice 自动调用 get如果直接获取实例并创建隐式 Provider<Foo>如果一个不存在。绑定(bind)注释适用于两种样式。

@Provides 的主要优点是紧凑,尤其是与匿名内部 Provider 实现相比。但是请注意,在某些情况下您可能希望支持 Provider 类:

  • 您可以创建自己的长生命周期 Provider 实例,可能带有构造函数参数,并将键绑定(bind)到这些实例而不是类文字。

    bind(Foo.class).toProvider(new FooProvisioner("bar", "baz"));
    
  • 如果您使用的是与 JSR 330 (javax.inject) 兼容的框架,您可以轻松绑定(bind)到 javax.inject.Provider 类或实例。 com.google.inject.Provider 扩展了该接口(interface)。

    bind(Foo.class).toProvider(SomeProviderThatDoesntKnowAboutGuice.class);
    
  • 您的 Provider 可能足够复杂,可以考虑到它自己的类中。根据您构建测试的方式,以这种方式测试您的 Provider 可能更容易。

  • 提供者可以扩展抽象类。使用@Provides 方法执行此操作可能并不容易或不直观。

  • 您可以将多个 key 直接绑定(bind)到同一个提供者。每个 @Provides 方法只生成一个绑定(bind),尽管您可以将其他键绑定(bind)到(此处为@Quux Foo)并让 Guice 进行第二次查找。

  • 如果您想(例如)在不使用 Guice 作用域或绑定(bind)的情况下缓存或内存实例,则提供程序很容易装饰或包装。

    bind(Foo.class).toProvider(new Cache(new FooProvisioner("bar", "baz")));
    

重要:虽然这对于 Guice 无法创建的类来说是一个很好的策略,但请记住 Guice 可以自动创建并注入(inject) Provider<T>对于你 bind 的任何 T以任何方式,包括类名、键或实例。除非涉及您自己的实际逻辑,否则无需创建显式提供程序。

关于java - Guice @Provides 方法与提供者类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28202882/

相关文章:

java - 将类对象注入(inject)另一个类中,而不将其添加到构造函数中

java - Google Guice 找不到类(class)

scala - 使用依赖注入(inject)测试带有 SecureSocial 的 Play2 应用程序

c# - CaSTLe Windsor 争论不休的生活方式

asp.net-mvc-3 - 工作单元和存储库模式是一起使用还是两个解决方案?

java - 如何使用 jar 分发 native 库?

java - 由于 obj.hasNext() 导致无限循环

c# - 可以一遍又一遍地构建 ServiceProvider 吗?

java 。打印 PDF。

java - 在搜索特定值时静默捕获 ClassCastException 是否安全?