我正在使用Guice来使用配置文件中的一些参数来初始化一个类
@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"));
}
这个类被注入另一个单独的类中。
class A{
@Inject private RetryServiceCaller retryServiceCaller;
}
但现在的问题是,由于这个新的A类是单例,我需要在每次有人使用这个类A时克隆retryServiceCaller。
我一直在研究FactoryModuleBuilder来使用它并为这个类创建一个工厂。但由于该类具有配置文件中的参数,因此无法找到使其工作的方法。
像这样的东西
class A{
@Inject private RetryServiceCaller.Factory retryServiceCallerFactory;
}
然后在我的RetryServiceCaller中实现这个
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告诉我错误说
No implementation for com.proxy.handlers.RetryServiceCaller$Factory was bound
答案 0 :(得分:1)
你的第一种方法应该可以正常工作。如果您不希望RetryServiceCaller
成为单例,请从提供程序方法中删除@Singleton
注释,并为每个注入点创建一个新实例。
辅助注射也可以在这里起作用,但这太过分了。如果你想走那条路:
interface RetryServiceCallerFactory {
RetryServiceCaller create(String configParam1, String configParam2);
}
public class RetryServiceCaller {
@AssistedInject
public RetryServiceCaller(String configParam1, String configParam2) {}
}
然后,在你的模块中
install(new FactoryModuleBuilder().build(Factory.class);
并在您的注射点
@Inject RetryServiceCallerFactory factory;
RetryServiceCaller create(JsonObject config) {
return factory.create(config.getFirstParam(), config.getSecondParam());
}
您可以参考documentation了解更多示例。
答案 1 :(得分:1)
Guice可以自动提供零参数工厂:您可以始终注入Foo
,而不是注入Provider<Foo>
。这使您可以随时随地致电fooProvider.get()
创建实例。您不必绑定到Provider
或使用Provides
方法来访问此内容;您可以注入Foo
或Provider<Foo>
是否使用bind(...).to(...)
类型绑定,toProvider
绑定,toInstance
绑定,@Provides
方法,或其他任何内容,Guice会致电get
或自动返回内部Provider
。
(返回的提供商也会尊重范围,因此您需要删除@Singleton
范围才能获得多个实例,并注意toInstance
绑定将总是返回相同的实例。)
这不是FactoryModuleBuilder的工作;当您需要混合相同类型的注入和非注入构造函数参数时,才使用FactoryModuleBuilder。
您完成的装订应如下所示:
@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
}