首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Guice用几种工厂方法和空参数辅助注入

Guice用几种工厂方法和空参数辅助注入
EN

Stack Overflow用户
提问于 2014-09-03 10:30:13
回答 3查看 6.5K关注 0票数 5

我有这个接口和简单的实现:

代码语言:javascript
运行
复制
public interface Data {    
}

import java.nio.file.Path;
import javax.annotation.Nullable;
import javax.inject.Inject;
import com.google.inject.assistedinject.Assisted;

public class SimpleData implements Data {
    @Inject
    public SimpleData(@Assisted @Nullable Path path) {
    }
}

我希望使用guice生成一个具有不同方法的Factory

代码语言:javascript
运行
复制
import java.nio.file.Path;

import javax.annotation.Nullable;

public interface Factory {
    Data create();
    Data load(@Nullable Path path);
}

但是,以下模块配置:

代码语言:javascript
运行
复制
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.assistedinject.FactoryModuleBuilder;

public class Main {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(
                binder -> binder.install(
                            new FactoryModuleBuilder().implement(Data.class, SimpleData.class)
                                                      .build(Factory.class)));
        Data data = injector.getInstance(Factory.class).create();
    }
}

失败:

代码语言:javascript
运行
复制
Exception in thread "main" com.google.inject.CreationException: Guice creation errors:

    1) No implementation for java.nio.file.Path annotated with @com.google.inject.assistedinject.Assisted(value=) was bound.
      while locating java.nio.file.Path annotated with @com.google.inject.assistedinject.Assisted(value=)
        for parameter 0 at SimpleData.<init>(SimpleData.java:10)
      at Factory.create(Factory.java:1)
      at com.google.inject.assistedinject.FactoryProvider2.initialize(FactoryProvider2.java:539)
      at com.google.inject.assistedinject.FactoryModuleBuilder$1.configure(FactoryModuleBuilder.java:335)

    1 error
        at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:435)
        at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:175)
        at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:109)
        at com.google.inject.Guice.createInjector(Guice.java:95)
        at com.google.inject.Guice.createInjector(Guice.java:72)
        at com.google.inject.Guice.createInjector(Guice.java:62)
        at Main.main(Main.java:9)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-09-09 07:03:32

我使用注释@AssistedInject解决了我的问题。引用javadoc:

当与FactoryModuleBuilder一起使用时,带有@AssistedInject注释的构造函数表明可以注入多个构造函数,每个构造函数具有不同的参数。

因此,我将注释和构造函数添加到SimpleData类中:

代码语言:javascript
运行
复制
public class SimpleData implements Data {
    @AssistedInject
    public SimpleData(@Assisted Path path) {

    }
    @AssistedInject
    public SimpleData() {

    }
}

我从工厂删除了@Nullable注释:

代码语言:javascript
运行
复制
import java.nio.file.Path;

public interface Factory {
    Data create();
    Data load(Path path);
}
票数 10
EN

Stack Overflow用户

发布于 2014-09-03 14:48:32

@Nullable并不意味着如果没有绑定,那么null就会被注入。它只允许编写绑定到null。如果您没有绑定并且没有适用的JIT绑定,那么注入将失败。

工厂的create()方法要求Guice找到一个@Assisted Path绑定,但是它显然找不到它,因为您从未创建过它,所以它失败了。

老实说,我不确定是否有一个干净的方法来实现这种违约。理想情况下,您应该用一些绑定注释标记Path,并为它添加一个默认绑定为null,但是@Assisted已经是一个绑定注释,并且不可能在一个注入点上有多个绑定注释。您可以尝试为@Assisted Path创建绑定。

代码语言:javascript
运行
复制
binder.bind(Path.class).annotatedWith(Assisted.class).toInstance(null);

但是,我不确定它是否会起作用,因为Assisted对Guice来说是特殊的。而且,即使它能起作用,它也不是很干净--可能会与接受Path的其他辅助工厂发生冲突。

票数 2
EN

Stack Overflow用户

发布于 2014-09-03 22:25:48

我希望Guice实现某种内部工厂接口,然后公开其他东西。如下所示:

代码语言:javascript
运行
复制
interface InternalFactory {
    Data load(@Nullable Path path);
}

public interface Factory {
    Data load();
    Data load(@Nullable Path path);
}

class FactoryImpl implements Factory {
    @Inject InternalFactory internalFactory;

    @Override
    public Data load() {
        return load(null); // Pass your defaults here
    }

    @Override
    public Data load(@Nullable Path path) {
        // Sadly you'll have to explicitly forward arguments here, but it's not
        // too bad IMO
        return internalFactory.load(path);
    }
}

public class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        install(new FactoryModuleBuilder()
                .implement(Data.class, SimpleData.class)
                .build(InternalFactory.class));

        bind(Factory).to(FactoryImpl.class);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25642021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档