JavaGuice:在创建模块之前实例化一个单例
在创建模块之前,是否可以用Guice实例化一个引用并将其分配给该引用,并在配置期间将该实例传递给要绑定的模块构造函数
以下是我的意思的一个例子: 我有一个方法,允许我根据接口的自定义实现创建对象,该接口作为可选的(如果用户不提供自定义实现,我们将使用默认实现)在构造函数中传递,这是通过将接口绑定到模块类中的特定实现来完成的
public static MyClass createMyClassObject(Optional<SpecialInterface> customSpecialInterfaceObject) {
SpecialInterface specialInterfacebject;
if(customSpecialInterfaceObject.isPresent() {
specialInterfaceObject = customSpecialInterfaceObject.get()
} else {
/* here I would like to bind it to an instance of the DefaultSpecialInterfaceObject but can't really do something like:
Injector injector = Guice.createInjector(myClassModule);
DefaultSpecialInterface instance = injector.getInstance(DefaultSpecialInterface.class);
as the module is yet to be created */
}
MyClassModule myClassModule = new MyClassModule(specialInterfaceObject);
Injector injector = Guice.createInjector(myClassModule);
return injector.getInstance(MyClass.class);
}
我目前使用类而不是实例来解决这个问题,比如下面的例子,但我不太喜欢这个解决方案。我很乐意看到更好的方法:
private static Class resolveSpecialInterfaceObject(Optional<SpecialInterface> customSpecialInterfaceObject) {
Class specialInterfaceObjectClass;
if (customSpecialInterfaceObject.isPresent()) {
specialInterfaceObjectClass= customSpecialInterfaceObject.get().getClass();
} else {
specialInterfaceObjectClass = DefaultSpecialInterface.class;
}
return specialInterfaceObjectClass;
}
public abstract class MyClassModule extends AbstractModule {
private final Class<SpecialInterface> specialInterfaceObjectClass;
public MyClassModule(Class<SpecialInterface> specialInterfaceObjectClass) {
this.specialInterfaceObjectClass= specialIntefaceObjectClass;
}
@Override
protected void configure() {
bind(SpecialInterface.class).to(specialInterfaceObjectClass);
}
}
编辑以下评论:
one more thing- didn't want to make the question too long; actually, I also want to perform another operation on the resulting instance of SpecialInterface, but only if it is the instance of DefaultSpecialInterface and I don't think it should be done in the Module. I was thinking if I could just have this bean up and running before, such as in Spring, so I could just pass it to the Module, but also use it in another method call before?
# 1 楼答案
你能把整个
Optional
用bind(...).toInstance(...)
吗如果只想在DefaultSpecialInterface上执行其他初始化操作,则有许多选项:
如果某种初始化对所有实现都很重要,并且可能太重而无法放入类构造函数中,那么在SpecialLinterface上添加
initialize
方法。将自定义设置为no-op,并为DefaultSpecialLinterface实现它如果初始化是DefaultSpecialInterface独有的,那么我看不出它不应该出现在模块中的原因。编写
@Provides
方法或绑定到Provider<SpecialInterface>
以正确创建和初始化DefaultSpecialInterface如果您的真正目标是将业务逻辑排除在模块之外,那么可以通过将其提取到一个独立的提供者或DefaultSpecialInterfaceFactory中来实现,该提供者或DefaultSpecialInterfaceFactory负责
请记住,Guice负责将完全构造的对象输入到对象图中,这意味着注入SpecialInterface应该让SpecialInterface通用契约的实现者随时可用。如果Guice需要执行一些初始化来实现这一点,那么让它这样做并不是不合理的,模块也不是一个不好的地方