Guice @Provides 方法与提供者类 [英] Guice @Provides Methods vs Provider Classes

查看:31
本文介绍了Guice @Provides 方法与提供者类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一个相当大的项目,该项目有很多注入.我们目前正在使用一个类来为每个需要一个注入的注入实现 Provider,并且它们大多只有一行 get 方法.

I'm working on a fairly large project that has a lot of injections. We're currently using a class that implements Provider for each injection that needs one, and they mostly have one line get methods.

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

It's starting to get annoying to create a new class every time I need a new provider. Is there any benefit to using provider classes over @Provides methods in my Module or vice-a-versa?

推荐答案

据我所知,它们在大多数简单情况下完全等效.

As far as I know, they're exactly equivalent for most simple cases.

/**
 * 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 都允许您注入 FooProvider,即使键绑定到类或实例.如果直接获取实例,Guice 会自动调用 get,如果不存在则创建隐式 Provider.绑定注释适用于两种风格.

In either style, Guice lets you inject Foo and Provider<Foo>, even if the key is bound to a class or instance. Guice automatically calls get if getting an instance directly and creates an implicit Provider<Foo> if one doesn't exist. Binding annotations work in both styles.

@Provides 的主要优点是紧凑,特别是与匿名内部 Provider 实现相比.但是请注意,在某些情况下,您可能希望使用 Provider 类:

The main advantage of @Provides is compactness, especially in comparison to anonymous inner Provider implementations. Note, however, that there might be a few cases where you'd want to favor Provider classes:

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

  • You can create your own long-lived Provider instances, possibly with constructor parameters, and bind keys to those instances instead of to class literals.

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

  • 如果您使用与 JSR 330 (javax.inject) 兼容的框架,您可以轻松绑定到 javax.inject.Provider 类或实例.com.google.inject.Provider 扩展了该接口.

  • If you're using a framework compatible with JSR 330 (javax.inject), you can easily bind to javax.inject.Provider classes or instances. com.google.inject.Provider extends that interface.

    bind(Foo.class).toProvider(SomeProviderThatDoesntKnowAboutGuice.class);
    

  • 您的 Provider 可能很复杂,可以将其分解为自己的类.根据您构建测试的方式,以这种方式测试您的提供程序可能更容易.

  • Your Provider may be complex enough to factor into its own class. Depending on how you've structured your tests, it may be easier to test your Provider this way.

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

    Providers can extend abstract classes. It may not be easy or intuitive to do this with @Provides methods.

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

    You can bind several keys to the same Provider directly. Each @Provides method produces exactly one binding, though you could bind other keys to the key (@Quux Foo here) and let Guice do a second lookup.

    如果您想(例如)在不使用 Guice 范围或绑定的情况下缓存或记忆实例,则提供程序很容易装饰或包装.

    Providers are easy to decorate or wrap, if you wanted to (for instance) cache or memoize instances without using Guice scopes or bindings.

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

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

    IMPORTANT: Though this is a good strategy for classes that Guice can't create, bear in mind that Guice can automatically create and inject a Provider<T> for any T that you bind in any way, including to a class name, key, or instance. No need to create an explicit provider unless there's actual logic of your own involved.

    这篇关于Guice @Provides 方法与提供者类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆