我有这个接口和简单的实现:
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
。
import java.nio.file.Path;
import javax.annotation.Nullable;
public interface Factory {
Data create();
Data load(@Nullable Path path);
}
但是,以下模块配置:
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();
}
}
失败:
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)
发布于 2014-09-09 07:03:32
我使用注释@AssistedInject
解决了我的问题。引用javadoc:
当与
FactoryModuleBuilder
一起使用时,带有@AssistedInject注释的构造函数表明可以注入多个构造函数,每个构造函数具有不同的参数。
因此,我将注释和构造函数添加到SimpleData
类中:
public class SimpleData implements Data {
@AssistedInject
public SimpleData(@Assisted Path path) {
}
@AssistedInject
public SimpleData() {
}
}
我从工厂删除了@Nullable注释:
import java.nio.file.Path;
public interface Factory {
Data create();
Data load(Path path);
}
发布于 2014-09-03 14:48:32
@Nullable
并不意味着如果没有绑定,那么null
就会被注入。它只允许编写绑定到null
。如果您没有绑定并且没有适用的JIT绑定,那么注入将失败。
工厂的create()
方法要求Guice找到一个@Assisted Path
绑定,但是它显然找不到它,因为您从未创建过它,所以它失败了。
老实说,我不确定是否有一个干净的方法来实现这种违约。理想情况下,您应该用一些绑定注释标记Path
,并为它添加一个默认绑定为null,但是@Assisted
已经是一个绑定注释,并且不可能在一个注入点上有多个绑定注释。您可以尝试为@Assisted Path
创建绑定。
binder.bind(Path.class).annotatedWith(Assisted.class).toInstance(null);
但是,我不确定它是否会起作用,因为Assisted
对Guice来说是特殊的。而且,即使它能起作用,它也不是很干净--可能会与接受Path
的其他辅助工厂发生冲突。
发布于 2014-09-03 22:25:48
我希望Guice实现某种内部工厂接口,然后公开其他东西。如下所示:
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);
}
}
https://stackoverflow.com/questions/25642021
复制相似问题