我正在尝试使用 Guice 3.0 AssistedInject
,它不会实例化工厂。
SSCCE代码:
父类
public class ParentClass() {
@Inject private MyFactory myFactory;
private final Foo foo;
private final Bar bar;
public ParentClass() {
if(myFactory == null) System.err.println("Error: I should have injected by now!");
foo = myFactory.create(new Map<String, Object>());
// etc.
}
}
工厂界面
public interface MyFactory {
Foo create(Map<String, Object> mapA);
Bar create(Map<String, Object> mapB, Map<String, Object> mapC);
}
模块
public class ParentModule extends AbstractModule {
@Override
protected void configure() {
install(new FactoryModuleBuilder()
.implement(Foo.class, FooImpl.class)
.implement(Bar.class, BarImpl.class)
.build(MyFactory.class));
}
福姆普尔
public class FooImpl implements Foo {
private final Map<String, Object> mapA;
@AssistedInject
public FooImpl(@Assisted Map<String, Object> mapA) {
this.mapA = mapA;
}
}
BarImpl
与FooImpl
非常相似。这里出了什么问题?另请注意,我在这里尝试了@AssistedInject
和@Inject
,都会导致错误。
输出:
Error: I should have injected by now!
Exception in thread "main" com.google.inject.ProvisionException: Guice provision errors:
1) Error injecting constructor, java.lang.NullPointerException
at ParentClass.<init>(ParentClass.java:7)
while locating com.my.package.ParentClass
1 error
at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:987)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1013)
at com.my.package.ParentMain.main(ParentMain.java:16)
Caused by: java.lang.NullPointerException
at com.my.package.ParentClass.<init>(ParentClass.java:9)
at com.my.package.ParentClass$$FastClassByGuice$$d4b3063a.newInstance(<generated>)
at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40)
... 8 more
请注意,第 9 行是第一次调用myFactory.create()
的线路
根据Guice的javadoc,字段注入是在构造函数注入之后执行的。
我假设您的ParentClass
实例是由 Guice 创建的。执行ParentClass
的构造函数时,尚未注入其myFactory
字段。
两件事。 若要在构造函数中使用注入,必须使用构造函数注入:
public class ParentClass {
private final Foo foo;
private final Bar bar;
@Inject
public ParentClass(MyFactory myFactory) {
if(myFactory == null) System.err.println("Error: I should have injected by now!");
this.foo = myFactory.create(new HashMap<String, Object>());
this.bar = myFactory.create(new HashMap<String, Object>(), new HashMap<String, Object>());
}
}
此外,由于您的工厂有两个相同类型的参数,因此您需要将它们命名:
public interface MyFactory {
Foo create(Map<String, Object> mapA);
Bar create(@Assisted("B") Map<String, Object> mapB, @Assisted("C") Map<String, Object> mapC);
}
和
public class BarImpl implements Bar {
private final Map<String, Object> mapA;
private final Map<String, Object> mapB;
@AssistedInject
public BarImpl(@Assisted("B") Map<String, Object> mapA, @Assisted("C") Map<String, Object> mapB) {
this.mapA = mapA;
this.mapB =mapB;
}
}