gpt4 book ai didi

java - Guice:在创建模块之前实例化单例

转载 作者:行者123 更新时间:2023-11-30 03:25:43 28 4
gpt4 key购买 nike

是否可以在创建模块之前使用 Guice 实例化并将单例分配给引用,并将该实例传递给在配置期间绑定(bind)的模块构造函数?

下面是我的意思的一个例子:我有一种方法,允许我根据接口(interface)的自定义实现来创建对象,该接口(interface)作为可选参数传入构造函数(如果用户不提供自定义实现,我们将使用默认实现),该方法正在通过将接口(interface)绑定(bind)到 Module 类中的特定实现来完成。 :

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?

最佳答案

你能拿走整个Optional吗?并使用bind(...).toInstance(...)

public static MyClass createMyClassObject(
Optional<SpecialInterface> customSpecialInterfaceObject) {

MyClassModule myClassModule = new MyClassModule(customSpecialInterfaceObject);
Injector injector = Guice.createInjector(myClassModule);
MyClassFactory instance = injector.getInstance(MyClassFactory.class);
return instance.createMyClassObject();
}

class MyClassModule extends AbstractModule {
private final Optional<SpecialInterface> customObject;

MyClassModule(Optional<SpecialInterface> customObject) {
this.customObject = customObject;
}

@Override public void configure() {
if (customObject.isPresent()) {
// Singleton by necessity: Guice doesn't know how to create another one.
bind(SpecialInterface.class).toInstance(customObject.get());
} else {
// Default scoped. Add ".in(Singleton.class)" if necessary.
bind(SpecialInterface.class).toInstance(DefaultSpecialInterfaceClass.class);
}
}
}

如果您只想在 DefaultSpecialInterface 上执行额外的初始化,那么您有多种选择:

  • 如果某种初始化对于所有实现都很重要,并且可能太重而无法放入类构造函数中,请添加 initialize特殊接口(interface)上的方法。将自定义接口(interface)设为无操作,并为 DefaultSpecialInterface 实现它。

  • 如果初始化对于 DefaultSpecialInterface 是唯一的,我认为它没有理由不应该出现在模块中。写一个@Provides方法或绑定(bind)到 Provider<SpecialInterface>正确创建并初始化 DefaultSpecialInterface。

  • 如果您的真正目标是将业务逻辑排除在模块之外,则可以通过将其提取到负责此操作的独立提供程序或 DefaultSpecialInterfaceFactory 中来实现。

    /p>

请记住,Guice 负责将完全构造的对象提供到对象图中,这意味着注入(inject) SpecialInterface 应该获得 SpecialInterface 通用合约的现成使用实现者。如果 Guice 需要执行一些初始化来实现这一点,那么让它这样做并不是没有道理的,并且模块并不是一个糟糕的地方。

关于java - Guice:在创建模块之前实例化单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30290789/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com