And a small follow-up with something like a probable bug in the Guice.
Consider the variant of code from the previous post - removed using the
factory from the constructor and added a "hack" postConstruct method
annotated with @inject to the Node class so the Guice will call it some time
after the node constructor finishes. This hack-postConstruct method creates
child nodes, so the overall result is that nodes are created by the factory
and their children are created automatically from the caller point of view
(the caller does not have to call "createChildrenLater()" after it gets a
instance node from the factory).
When run, this variant does not throw any ProvisionExceptions, but it prints
the "!!! the factory returned THIS node instead of the new node !!!"
message, which means that the instance returned from the call to factory is
equal to the "this" object, probably the previous object created by this
factory. This is a bug in the Guice - it should have thrown
ProvisionException as before if it does not like the way I use the factory.
Of course better yet, it should have returned a new instance, as expected.
If the "@inject postConstruct()" method is modified to "@inject
postConstruct( Injector injector )" (a parameter of Injector type is added,
but the method body does not use it), then the code will work as was
expected from the beginning - there will be no ProvisionExceptions and
factory will return unique instances on each call.
How the factory manages to return the same instance in the "@inject
method()" variant?
Why the difference between "@inject method()" and "@inject method( Injector
injector )" variants?
=== start of @inject postConstruct() variant ===
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.FactoryModuleBuilder;
public class TestGuiceModule {
public static void main( String[] args ) {
Injector injector = Guice.createInjector( new AbstractModule() {
@Override
protected void configure() {
install( new FactoryModuleBuilder()
.implement( new TypeLiteral<Node<Integer>>() {},
IntegerNode.class )
.build( new TypeLiteral<NodeFactory<Integer>>()
{} ) );
}
} );
NodeFactory<Integer> factory = injector.getInstance( Key.get( new
TypeLiteral<NodeFactory<Integer>>() {} ) );
System.out.println( "create a node first, create children later" );
Node<Integer> node1 = factory.createNode( 0 );
System.out.println();
System.out.println( "create a node and create some children in its
constructor" );
Node<Integer> node2 = factory.createNode( 1 );
}
public abstract static class Node<E> {
public E value;
public Node( E value ) {
this.value = value;
}
@Inject
private void postConstruct() {
System.out.println( "TestGuiceModule$Node.postConstruct" );
createChildrenLater();
}
public abstract void createChildrenLater();
}
public static interface NodeFactory<E> {
Node<E> createNode( E value );
}
public static class IntegerNode extends Node<Integer> {
private final NodeFactory<Integer> factory;
@Inject
public IntegerNode( @Assisted Integer value, NodeFactory<Integer>
factory ) {
super( value );
System.out.println( "TestGuiceModule$IntegerNode.IntegerNode,
this identity=" + System.identityHashCode( this ) + ", value=" + value + ",
factory identity=" + System.identityHashCode( factory ) );
this.factory = factory;
}
@Override
public void createChildrenLater() {
if ( value > 0 ) {
System.out.println(
"TestGuiceModule$IntegerNode.createChildrenLater" );
Node<Integer> child = factory.createNode( value - 1 );
if ( this == child ) {
System.out.println( "\t!!! the factory returned THIS
node instead of the new node !!!" );
}
}
}
}
}
=== end of @inject postConstruct() variant ===
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice?hl=en.