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.
Domanda
I am trying to use Guice 3.0 AssistedInject
, and it won't instantiate the factory.
SSCCE Code:
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
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()
Soluzione
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.
Altri suggerimenti
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;
}
}