Guice FactoryModuleBuilder一个带有构造函数参数的实例 [英] Guice FactoryModuleBuilder an instance with constructor parameters

查看:224
本文介绍了Guice FactoryModuleBuilder一个带有构造函数参数的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Guice初始化一个带有配置文件中一些参数的类

I´m using Guice to initalize a class with some arguments from a config file

@Provides
@Singleton
RetryServiceCaller provideMaxRetryAttempts(@Named("config") JsonObject config) throws IOException {
    JsonObject retryDetails = config.getJsonObject("retry_details");
    return new RetryServiceCaller(retryDetails.getInteger("maxRetryAttempts"), retryDetails.getInteger("upperBoundary"), retryDetails.getInteger("lowerBoundary"),
                                  retryDetails.getLong("multiplicationFactor"), retryDetails.getInteger("timeout"), retryDetails.getInteger("increaseTimeout"));
}

该类也注入到另一个单例类中.

This class is injected in another class which is singleton as well.

class A{
   @Inject private RetryServiceCaller retryServiceCaller;
}

但是现在的问题是,由于这个新的类A是单例,因此每次有人使用该类A时,我都需要克隆retryServiceCaller.

But now the problem is that since this new class A is singleton, I need to clone the retryServiceCaller every time that somebody use this class A.

我一直在研究FactoryModuleBuilder以使用它并为该类创建工厂.但是由于该类具有配置文件中的参数,所以我找不到使它起作用的方法.

I´ve been investigating FactoryModuleBuilder to use it and create a factory for this class. But since the class has parameters from the config file I could not find the way to make it works.

类似这样的东西

  class A{
       @Inject private RetryServiceCaller.Factory retryServiceCallerFactory;

   }

然后在我的RetryServiceCaller中实现

Then in my RetryServiceCaller implement this

public interface Factory {
    @Inject
    RetryServiceCaller create();
}


@Inject
public RetryServiceCaller(int maxRetryAttempts, int upperBoundary, int lowerBoundary, long multiplicationFactor, int timeout, int incrementTimeout) {
    this.maxRetryAttempts = maxRetryAttempts;
    this.upperBoundary = upperBoundary;
    this.lowerBoundary = lowerBoundary;
    this.multiplicationFactor = multiplicationFactor;
    this.timeout = timeout;
    this.incrementTimeout = incrementTimeout;
}

但是guice让我说错了

But guice throw me errors saying

No implementation for com.proxy.handlers.RetryServiceCaller$Factory was bound

推荐答案

Guice可以自动提供零参数工厂:不必注入Foo,您总是可以注入Provider<Foo>.这样,您可以随时随地调用fooProvider.get()创建实例.您不必绑定到Provider或使用Provides方法来访问它.您可以注入FooProvider<Foo>,无论您使用bind(...).to(...)类型绑定,toProvider绑定,toInstance绑定,@Provides方法还是其他任何方式,Guice都会调用get或自动返回内部Provider.

Guice can automatically provide a zero-argument factory: Instead of injecting Foo, you can always inject Provider<Foo>. This allows you to call fooProvider.get() to create an instance whenever and wherever you'd like. You don't have to bind to a Provider or use a Provides method to get access to this; you can inject Foo or Provider<Foo> whether you use a bind(...).to(...) type binding, a toProvider binding, a toInstance binding, a @Provides method, or anything else, and Guice will call get or return an internal Provider automatically.

(返回的Provider也将遵守范围,因此您需要删除@Singleton范围才能获取多个实例,并且请注意toInstance绑定将始终 返回相同的实例.)

(The returned Provider will also respect scopes, so you'll need to drop your @Singleton scope in order to get more than one instance, and be aware that toInstance bindings will always return the same instance.)

这不是FactoryModuleBuilder的工作;仅在需要混合使用相同类型的注入和非注入构造函数参数时才使用FactoryModuleBuilder.

This is not a job for FactoryModuleBuilder; only use FactoryModuleBuilder when you need to mix injected and non-injected constructor parameters in the same type.

您完成的绑定应如下所示:

Your finished binding should look like this:

@Provides
/* NOT @Singleton */
RetryServiceCaller provideMaxRetryAttempts(@Named("config") JsonObject config) throws IOException {
    JsonObject retryDetails = config.getJsonObject("retry_details");
    return new RetryServiceCaller(retryDetails.getInteger("maxRetryAttempts"), retryDetails.getInteger("upperBoundary"), retryDetails.getInteger("lowerBoundary"),
                                  retryDetails.getLong("multiplicationFactor"), retryDetails.getInteger("timeout"), retryDetails.getInteger("increaseTimeout"));
}

在您的课堂上:

@Inject public YourCallerConsumer(Provider<RetryServiceCaller> callerProvider) {
  this.callerProvider = callerProvider;
}

public void doAction() {
  RetryServiceCaller newCaller = callerProvider.get();
  // interact with caller
}

这篇关于Guice FactoryModuleBuilder一个带有构造函数参数的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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