问题描述
我正在用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
方法来访问它.您可以注入Foo
或Provider<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一个带有构造函数参数的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!