Re: Comment on Scopes in google-guice

31 views
Skip to first unread message

google...@googlecode.com

unread,
Feb 3, 2011, 9:54:46 AM2/3/11
to google-g...@googlegroups.com
Comment by szymon.w...@gmail.com:

I have a @SessionScoped DAO that's being injected into a Stripes framework
Interceptor constructor that seems to be found from the interceptor (on
subsequent calls) but is not being injected into a service in the same
request (and session). Why isn't the same instance (initialized in the
interceptor) being reused in the service (which is in a different package
in the same project)?

Making the DAO a @Singleton does the trick, but is unacceptable as the DAO
stores information that must remain consistent throughout a user's session
on an application that has multiple users who would be sharing the same DAO
instance.

For more information:
http://code.google.com/p/google-guice/wiki/Scopes

google...@googlecode.com

unread,
Feb 3, 2011, 11:39:09 AM2/3/11
to google-g...@googlegroups.com
Comment by ffa...@gmail.com:

Please ask questions on the groups mailing list
(http://groups.google.com/group/google-guice), thanks.

google...@googlecode.com

unread,
Feb 16, 2011, 8:55:39 AM2/16/11
to google-g...@googlegroups.com
Comment by kristian...@googlemail.com:

Can someone confirm whether using @Provides is effectively the same as
using a provider ? Little confused between the two.

google...@googlecode.com

unread,
Feb 21, 2011, 2:40:01 PM2/21/11
to google-g...@googlegroups.com
Comment by tuxSla...@gmail.com:

Why don't you provide "Thread" scope too for non-web applications? It looks
logical to have such scope and its a tricky to implement without AOP.

google...@googlecode.com

unread,
Feb 23, 2011, 1:39:24 AM2/23/11
to google-g...@googlegroups.com
Comment by scottro...@gmail.com:

I was just wondering if there is any way to implement a callback to perform
some logic when an object goes out of "Scope" ? For example, I have a
Request scoped @Provides method, that creats an object and does some
initialization on it, I need a way to do some cleanup when the scope is
exiting. -thanks

google...@googlecode.com

unread,
Mar 15, 2011, 3:25:56 PM3/15/11
to google-g...@googlegroups.com
Comment by sne...@gmail.com:

I'd like to see the "@Provides @Singleton" example expanded. Is it
suppossed to call a "new" object like the documentation? Seems stange for a
singleton pattern.

DatabaseTransactionLog transactionLog = new DatabaseTransactionLog();
transactionLog.setJdbcUrl("jdbc:mysql://localhost/pizza");
transactionLog.setThreadPoolSize(30);
return transactionLog;

google...@googlecode.com

unread,
Mar 15, 2011, 4:05:05 PM3/15/11
to google-g...@googlegroups.com
Comment by cgdec...@gmail.com:

As with things bound using `bind(...).to(...)`, Guice handles the scoping
for you. In the case of an `@Provides @Singleton` provider method, it'll
ensure that it only calls the method once and reuses the object that is
returned.

google...@googlecode.com

unread,
Aug 31, 2011, 2:40:57 PM8/31/11
to google-g...@googlegroups.com
Comment by da...@doubledowninteractive.com:

There's a massive conceptual problem regarding @Singleton scope and default
scope. A @Singleton that depends on a default scope object is wholly
incompatible, just as much as having @Singleton depend on an object with
@Session or @Request scope. The javadoc states that @Singleton indicates
thread safety: that's about as good as Java gets in terms of a binding
contract between your objects and thread safety and immutability (oh,
scala, I miss you).

This is exactly what thang...@gmail states above... except that the problem
isn't with using the universally accepted singleton pattern, the problem is
the notion that using the default scope is in any way useful or safe. Or
architecturally valid. For the reasons he stated. Unless you're new to
Java, coming from a PHP worldview, and every single object is default
scoped and each thread uses a whole new instance of your application's
objects.

The whole point of DI is to remove tight, static coupling between objects.
This is done to provide proper abstraction and promoting good unit testing
(that means readable, clean code). At some point, your application has some
object that calls a method on another object that has been injected. If
that object is not @Singleton scoped, you probably had to call
Injector.getInstance(). That call right there is a tight coupling, breaking
the DI paradigm, introducing non-unit-testable code.

The idea that performance is some sort of valid excuse for using the
default scope is absolute nonsense. Object construction is not a
performance issue. If your objects take too long to construct, you're doing
too much in your constructor. If your application takes a few seconds to
start up... you don't really have a performance issue.

Calling Injector.getInstance() is bad. Mixing @Singleton and default scope
is a confusing, hidden contract. Sure, you know what you did, but does your
team? After you leave? After they leave?

Guice ought to throw an error at startup if a @Singleton depends on any
other scope. I cannot think of a situation where allowing them to be mixed
would be intended.

google...@googlecode.com

unread,
Aug 31, 2011, 2:45:00 PM8/31/11
to google-g...@googlegroups.com
Comment by da...@doubledowninteractive.com:

A better pattern to use when dealing stateful objects that require
dependencies is create a singleton factory. It contains the necessary
dependencies, and has a method that takes in the state that the stateful
object requires. You can mock out the factory, ignore what should be
transparent DI in the test, and avoid mixing scopes.

google...@googlecode.com

unread,
Aug 31, 2011, 2:49:05 PM8/31/11
to google-g...@googlegroups.com
Comment by davec...@gmail.com:

For more information:
http://code.google.com/p/google-guice/wiki/Scopes

google...@googlecode.com

unread,
Aug 31, 2011, 2:53:09 PM8/31/11
to google-g...@googlegroups.com
Comment by davec...@gmail.com:

A better pattern to use when dealing stateful objects that require
dependencies is create a singleton factory. It contains the necessary
dependencies, and has a method that takes in the state that the stateful
object requires. You can mock out the factory, ignore what should be
transparent DI in the test, and avoid mixing scopes.

For more information:
http://code.google.com/p/google-guice/wiki/Scopes

google...@googlecode.com

unread,
Sep 22, 2011, 4:42:19 PM9/22/11
to google-g...@googlegroups.com
Comment by vfunst...@gmail.com:

davec..., you can think of Injector as an object factory, calls to which
will be replacing constructor invocations that would otherwise contain
hardwired dependencies. What does this have to do with scoping though?
Depending on how you tell it to scope your objects, Guice will do the right
thing. Either I don't get your point, or you don't really get the concept
of DI in general.

google...@googlecode.com

unread,
Jan 5, 2012, 1:18:42 AM1/5/12
to google-g...@googlegroups.com
Comment by clifford...@gmail.com:

Spring choose singleton as the default scope for it's IoC, Guice choose
instance (what spring calls 'prototype'). Just curious what motivated this
decision?

google...@googlecode.com

unread,
Jan 5, 2012, 8:39:33 AM1/5/12
to google-g...@googlegroups.com
Comment by mccu...@gmail.com:

Having 'prototype' or 'per-instance' scope as the default makes sense when
you look into the design of Guice and the re-usability of Providers - imho
the main point being that you can build a singleton on top of a
per-instance Provider, but not the other way round.

google...@googlecode.com

unread,
Mar 18, 2013, 10:28:16 PM3/18/13
to google-g...@googlegroups.com
Comment by fcin...@gmail.com:

I'm a bit confused about the behaviour of using Provider and @Singleton
simultaneously.

I tried to use a TransactionLogProvider to supply an instance of
FileTransactionLog which is annotated with @Singleton. But multiple
instances are still instantiated.

Please refer to the snippets below. Two instances of FileTransactionLog
would be created, which means @Singleton doesn't work for this scenario.

BillingModule.java
{{{
protected void configure() {
bind(TransactionLog.class).toProvider(TransactionLogProvider.class);
//singleton only works if it's explicitly declared as following

//bind(TransactionLog.class).toProvider(TransactionLogProvider.class).in(Singleton.class);
}

}}}

TransactionLogProvider.java
{{{
public TransactionLog get() {
return new FileTransactionLog();
}
}}}

FileTransactionLog with @Singleton
{{{
@Singleton
public class FileTransactionLog implements TransactionLog {
public FileTransactionLog() {
System.out.println("new FileTransactionLog instance");
}
}
}}}

Bootstrap
{{{
public static void main(String[] args) {
Injector injector = Guice.createInjector(new BillingModule());

injector.getInstance(RealBillingService.class);
injector.getInstance(RealBillingService.class);

Christian Goudreau

unread,
Mar 19, 2013, 4:37:09 PM3/19/13
to google-g...@googlegroups.com
bind(TransactionLog.class).toProvider(TransactionLogProvider.class);
In this case, where @Singleton is added on top of FileTransactionLog, only FileTransactionLog is a singleton, not TransactionLog. Those are two different type.

 bind(TransactionLog.class).toProvider(TransactionLogProvider.class).in(Singleton.class);
This binds TransactionLog as a singleton, thus will always return the same instance when returning TransactionLog.

If you were to inject FileTransactionLog directly in your first example, you would get the singleton you were expecting. 


--
You received this message because you are subscribed to the Google Groups "google-guice-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice-dev+unsubscribe@googlegroups.com.

To post to this group, send email to google-guice-dev@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.





--
Christian Goudreau

google...@googlecode.com

unread,
May 14, 2013, 6:01:29 AM5/14/13
to google-g...@googlegroups.com
Comment by bells...@gmail.com:

I'm a bit confused too

google...@googlecode.com

unread,
May 17, 2013, 7:05:57 AM5/17/13
to google-g...@googlegroups.com
Comment by mccu...@gmail.com:

Your TransactionLogProvider is calling {{{new FileTransactionLog()}}}
meaning that this instance is managed by the JVM outside of the Injector,
therefore the @Singleton annotation has no effect.

For @Singleton annotations declared on the implementation class this will
only apply when Guice creates the implementation itself, for example:
{{{
@Inject FileTransactionLog log;
}}}
If there's no explicit binding to FileTransactionLog then Guice will
attempt to construct it using a just-in-time binding. At this point if
Guice sees @Singleton on the implementation then it will wrap the above
binding inside a singleton scope and use that to inject the log.
{{{
bind(TransactionLog.class).to(FileTransactionLog.class);
...
@Inject TransactionLog log;
}}}
Guice follows the linked binding to the untargetted FileTransactionLog at
which point it will create a just-in-time binding as above (wrapped in
singleton scope) and use that to inject log.
{{{
bind(TransactionLog.class).toProvider(TransactionLogProvider.class);
...
@Inject TransactionLog log;
}}}
Guice follows the linked binding to the provider at which point it will
create the provider and call get() to retrieve an instance of
TransactionLog. It doesn't wrap any scope around the provider - to get
Guice to do that you would need to scope the linked binding
using "bind(TransactionLog.class).toProvider(TransactionLogProvider.class).in(Singleton.class)".

Note that declaring @Singleton on the provider implementation class would
only mean that the same provider instance would be used each time to supply
TransactionLogs (rather than a new provider being constructed as it was
needed).
Reply all
Reply to author
Forward
0 new messages