问题
I am trying to use Guice 3.0 AssistedInject
, and it won't instantiate the factory.
SSCCE Code:
Parent class
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.
}
}
Factory Interface
public interface MyFactory {
Foo create(Map<String, Object> mapA);
Bar create(Map<String, Object> mapB, Map<String, Object> mapC);
}
Module
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));
}
FooImpl
public class FooImpl implements Foo {
private final Map<String, Object> mapA;
@AssistedInject
public FooImpl(@Assisted Map<String, Object> mapA) {
this.mapA = mapA;
}
}
BarImpl
is very similar to FooImpl
. What is going wrong here? Note also that I tried both @AssistedInject
and @Inject
here, both cause the error.
Output:
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
Note that line 9 is the line of the first call to myFactory.create()
回答1:
According to Guice's javadoc, field injection is performed after constructor injection.
I assume your ParentClass
instance is created by Guice. When your ParentClass
's constructor is executed, its myFactory
field has not been injected yet.
回答2:
Two things. To use an injection in a constructor, you must use a constructor injection:
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>());
}
}
Also, since your factory has two parameters of the same type, you need to name them:
public interface MyFactory {
Foo create(Map<String, Object> mapA);
Bar create(@Assisted("B") Map<String, Object> mapB, @Assisted("C") Map<String, Object> mapC);
}
and
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;
}
}
来源:https://stackoverflow.com/questions/14760219/guice-assistedinject-wont-inject-the-factory