Singleton by default

3,540 views
Skip to first unread message

Andrey

unread,
Jan 7, 2010, 12:48:14 PM1/7/10
to google-guice
Hello!

How can I make Guice create singletons by default?

At the moment ALL my classes are injected as singletons so if it was
default scope I could remove all such lines from the module:

bind(ProductsController.class).in(Singleton.class);
bind(ProductService.class).in(Singleton.class);
...

Look at the Spring for example - singleton is the default scope in
Spring and it is correct, because we usually use injection for high
level services, controllers and other singletons. If we need new
instance every time we just use new, we do not usually need IOC for
that. So it is very strange for me that Guice's default scope is
"new".
Can I change this?

Thanks in advance!

Jeremy Chone

unread,
Jan 7, 2010, 1:15:27 PM1/7/10
to google...@googlegroups.com
I do not know the answer to your question. However, you could put @Singleton on your classes. "Marking" singleton classes with @Singleton is not a bad practice anyway. 


Jeremy,


--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To post to this group, send email to google...@googlegroups.com.
To unsubscribe from this group, send email to google-guice...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.






--
Jeremy Chone
+1 415 699 9912

Stuart McCulloch

unread,
Jan 7, 2010, 1:45:39 PM1/7/10
to google...@googlegroups.com
2010/1/8 Andrey <min...@gmail.com>

The default scope is "no scope", ie. provide a new instance on each request

imho this is a cleaner default because singletons, request and session scopes,
etc. can all be implemented as separate layers on top of the default behaviour:

     bind(ProductsController.class)
vs
     bind(ProductsController.class).in(Singleton.class)
vs
     bind(ProductsController.class).in(RequestScoped.class)

Can I change this?

Well as Jeremy said you could add @Singleton to the classes (which is
also a good hint to the developer to be extra careful about thread safety)

or you could write utility methods (or a custom module class) to simplify
your instructions - ie. what you normally do when you see duplicate code.
For example you could have a set of bindSingleton methods that map to
the appropriate "bind(...).in( Singleton.class )" calls.

Finally the Guice SPI lets you traverse module bindings - you could use
this to convert a module (on-the-fly) with no-scope bindings into one that
has singletons as the default:

     http://code.google.com/p/google-guice/wiki/ExtendingGuice
     # see the Module and Elements javadoc

HTH

Thanks in advance!

--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To post to this group, send email to google...@googlegroups.com.
To unsubscribe from this group, send email to google-guice...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.

--
Cheers, Stuart

Dhanji R. Prasanna

unread,
Jan 7, 2010, 5:47:26 PM1/7/10
to google...@googlegroups.com
You could make your own subclass of abstract module that bound everything in singleton scope unless explicitly specified.

Dhanji.

Eelco Hillenius

unread,
Jan 7, 2010, 10:42:10 PM1/7/10
to google...@googlegroups.com
> that. So it is very strange for me that Guice's default scope is
> "new".

Imho this is a good default because it is the safest one. Being
explicit about whether something is a singleton forces developers to
think about the consequences. It may also be more efficient for
objects that are cheap to construct.

If you want everything to be bound as a singleton but without much
pre-registration, how about using classpath scanning? There's a nice
utility class in sitebricks
(http://www.google.com/codesearch/p?hl=en#iHNmFuHrx4M/trunk/sitebricks/src/main/java/com/google/sitebricks/Classes.java&q=classes%20package:http://google-sitebricks%5C.googlecode%5C.com&sa=N&cd=1&ct=rc)
that makes this easy to do, and if your services follow a naming
pattern or implement a certain interface you could scan on that and
bind everything you find as a singleton. Quite possibly this is
horrible to Guice's developers, but it works and is easy to implement.

Eelco

Sam Berlin

unread,
Jan 8, 2010, 3:43:30 PM1/8/10
to google...@googlegroups.com
I was experimenting last night with the SPI because I took the email as a challenge to see if I could make a singletonize(Module... modules) method that would return a Module where all the unscoped elements were converted to singletons.  The main barrier I ran into was that there appears to be no way to modify an element after its created, and no good way to get the building blocks of a specific element in order to recreate it in a different way.  If there was one thing that could change to make this possible it would be to somehow expose something similar to the 'withScoping' method in BindingImpl.  The best way I can think to do this is to have an SPI class Rescoper that is similar to AbstractBindingBuilder, but much more limited.  In a nutshell, it would look like:

com.google.inject.spi.Rescoper
  Binding rescope(Binding, Scope) { delegate to com.google.inject.internal.BindingRescoper.rescope }

com.google.inject.internal.BindingRescoper
Binding rescope(Binding, Scope) { return binding.withScoping(Scoping.forInstance(Scope)); }

If folks think that idea of being able to modify an element after it's created more generally useful, this could be fleshed out more to be more of a BindingEditor.

Sam

Sam Berlin

unread,
Jan 17, 2010, 12:43:34 PM1/17/10
to google...@googlegroups.com
I added a new issue (issue 460 @
http://code.google.com/p/google-guice/issues/detail?id=460 ) that has
a patch to allow something like this with the API of:

Module newModule = Modules.rewrite(new MyModule())
.withScope(new NoScopeMatcher(), Scopes.SINGLETON)
.build();

Sam

Witold Szczerba

unread,
Jan 18, 2010, 8:00:37 PM1/18/10
to google...@googlegroups.com
2010/1/7 Andrey <min...@gmail.com>:
> [...] If we need new

> instance every time we just use new, we do not usually need IOC for
> that. So it is very strange for me that Guice's default scope is
> "new".

You cannot compare Guice's "new" to constructor's "new".
Whether singleton scope, no scope or whatever scope, Guice will inject
all the dependencies for you, which is not the case when you just call
the constructor.
One should not mix application with "new" here or there (excluding
leaf objects), here is why:
http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/
I am not sure, but I suppose that in my application "no scopes" are
even more common that singletons.

Reply all
Reply to author
Forward
0 new messages