@Inject always creating new object

1,750 views
Skip to first unread message

Matt

unread,
Jun 19, 2009, 12:28:37 AM6/19/09
to google-guice
I'm new to Guice, and I'm using injection within an interceptor, with
requestInjection() in my module.

The interceptor is being called just fine, so my module appears to be
good. The problem is that @Inject is always creating a new object
using the constructor for that object instead of injecting the
original pre-initialized one. What am I missing here?

public class TestInterceptor implements MethodInterceptor {
@Inject MyObject obj; // always a newly-created object

public Object invoke(...) { obj.doSomething(); ... }
}

public class TestImpl implements Test {
@Inject MyObject obj;

public TestImpl() {
Injector injector = Guice.createInjector(new TestModule());
obj = injector.getInstance(MyObject.class);
obj.init(); // I want access to this already initialized object in
the interceptor
}
}

Thanks.

jordi

unread,
Jun 19, 2009, 4:05:14 AM6/19/09
to google...@googlegroups.com
hey there, 

you should define a @Singleton scope for you object. Guice by default creates a new object every time you request that object, that's called no scope.

You could place the @Singleton annotation directly on MyObject class at type level, or in your TestModule bind the scope to your object: bind(MyObject.class).in(Scopes.SINGLETON);

hope this helps!

jordi

Stuart McCulloch

unread,
Jun 19, 2009, 5:41:01 AM6/19/09
to google...@googlegroups.com
2009/6/19 Matt <mte...@gmail.com>

I'm new to Guice, and I'm using injection within an interceptor, with
requestInjection() in my module.

The interceptor is being called just fine, so my module appears to be
good.  The problem is that @Inject is always creating a new object
using the constructor for that object instead of injecting the
original pre-initialized one.  What am I missing here?

Hi Matt, as the main project page says @Inject is the new new ;)

so wherever you use @Inject you should expect to get a new instance,
unless you've used a scoped binding like singleton - in which case you
will get the same instance for that binding (per-injector).

however, it looks like you just want to get the original instance to use in
the AOP call - you can get this via the "MethodInvocation" object that's
passed in to the method interceptor

for example, from http://aopalliance.sourceforge.net/doc/org/aopalliance/intercept/MethodInterceptor.html

 class TracingInterceptor implements MethodInterceptor {
   Object invoke(MethodInvocation i) throws Throwable {
     System.out.println("method "+i.getMethod()+" is called on "+i.getThis()+" with args "+i.getArguments());
     Object ret=i.proceed();
     System.out.println("method "+i.getMethod()+" returns "+ret);
     return ret;
   }
 }

so there's no need to inject the original instance, as it's already available to you

HTH

public class TestInterceptor implements MethodInterceptor {
 @Inject MyObject obj; // always a newly-created object

 public Object invoke(...) { obj.doSomething(); ... }
}

public class TestImpl implements Test {
 @Inject MyObject obj;

 public TestImpl() {
   Injector injector = Guice.createInjector(new TestModule());
   obj = injector.getInstance(MyObject.class);
   obj.init(); // I want access to this already initialized object in
the interceptor
 }
}

Thanks.






--
Cheers, Stuart

Matt

unread,
Jun 19, 2009, 5:03:01 PM6/19/09
to google-guice
Thanks Stuart and Jordi for the suggestions.

I ended up just using MethodInvocation.getThis() to get an instance of
the calling object, having missed seeing that method in the
documentation previously.

On Jun 19, 2:41 am, Stuart McCulloch <mccu...@gmail.com> wrote:
> 2009/6/19 Matt <mter...@gmail.com>
>
>
>
> > I'm new to Guice, and I'm using injection within an interceptor, with
> > requestInjection() in my module.
>
> > The interceptor is being called just fine, so my module appears to be
> > good.  The problem is that @Inject is always creating a new object
> > using the constructor for that object instead of injecting the
> > original pre-initialized one.  What am I missing here?
>
> Hi Matt, as the main project page says @Inject is the new new ;)
>
> so wherever you use @Inject you should expect to get a new instance,
> unless you've used a scoped binding like singleton - in which case you
> will get the same instance for that binding (per-injector).
>
> however, it looks like you just want to get the original instance to use in
> the AOP call - you can get this via the "MethodInvocation" object that's
> passed in to the method interceptor
>
> for example, fromhttp://aopalliance.sourceforge.net/doc/org/aopalliance/intercept/Meth...
Reply all
Reply to author
Forward
0 new messages