How can I make a provider create singleton object?

4,472 views
Skip to first unread message

zhaoyi

unread,
Aug 14, 2009, 10:38:00 PM8/14/09
to google-guice
This is my code. Whenever I call mouseActionFactoryProvider.get(), it
will return create an instance. It seems that the @Singleton doesn't
work here.

@Singleton
public class MouseActionFactoryProvider implements
Provider<MouseActionListenerFactory> {

@Override
@Singleton
public MouseActionListenerFactory get() {
return new MouseActionListenerFactory();
}
}

public class MouseActionModule extends AbstractModule {

@Override
protected void configure() {
bind(MouseActionListenerFactory.class).toProvider(
MouseActionFactoryProvider.class).in(Singleton.class);
bind(MouseActionFactoryProvider.class).in(Singleton.class);
}

}

public static void main(String []args){
Injector injector = Guice.createInjector(new
MouseActionModule());
mouseActionFactoryProvider = injector
.getInstance(MouseActionFactoryProvider.class);

}

Max Bowsher

unread,
Aug 15, 2009, 6:55:54 AM8/15/09
to google...@googlegroups.com
zhaoyi wrote:
> This is my code. Whenever I call mouseActionFactoryProvider.get(), it
> will return create an instance. It seems that the @Singleton doesn't
> work here.
>
> @Singleton
> public class MouseActionFactoryProvider implements
> Provider<MouseActionListenerFactory> {
>
> @Override
> @Singleton
> public MouseActionListenerFactory get() {
> return new MouseActionListenerFactory();
> }
> }

Scope annotations apply to providers as a whole, annotating the get()
method with @Singleton is erroneous and ignored.

> public class MouseActionModule extends AbstractModule {
>
> @Override
> protected void configure() {
> bind(MouseActionListenerFactory.class).toProvider(
> MouseActionFactoryProvider.class).in(Singleton.class);
> bind(MouseActionFactoryProvider.class).in(Singleton.class);
> }
>
> }

What you have done here is:

1) Bind MouseActionListenerFactory, in singleton scope, to be produced
via your Provider.

2) ENTIRELY SEPARATELY bind a different instance of the Provider as a
second singleton.

> public static void main(String []args){
> Injector injector = Guice.createInjector(new
> MouseActionModule());
> mouseActionFactoryProvider = injector
> .getInstance(MouseActionFactoryProvider.class);
>
> }

And here you retrieve the singleton created by the second binding. Any
calls you make to its get() method are NOT MANAGED by Guice, so each one
runs the get() method afresh.

You should REMOVE the second binding from your Module, and you should
call injector.getProvider(x) in the case above where you are currently
calling injector.getInstance(x).

Max.

signature.asc

zhaoyi

unread,
Aug 16, 2009, 10:04:12 PM8/16/09
to google-guice
I have tried that remove the second binding from the Module and use
injector.getProvider(x), but I still get different instance. See my
code below:

Injector injector = Guice.createInjector(new MouseActionModule());

mouseActionFactoryProvider = injector.getProvider(
MouseActionFactoryProvider.class).get();
System.out.println(mouseActionFactoryProvider.get());
System.out.println(mouseActionFactoryProvider.get());
System.out.println(mouseActionFactoryProvider.get());
System.out.println(mouseActionFactoryProvider.get());

Each time I call mouseActionFactoryProvider.get(), I will get the new
instance.
>  signature.asc
> < 1KViewDownload

Dan Godfrey

unread,
Aug 17, 2009, 6:24:34 AM8/17/09
to google-guice
You're still creating a new instance of the listener factory at every
get(), as guice isn't managing the provider. You need to get an
instance of type MouseActionListenerFactory rather than the Provider.
So

Injector injector = Guice.createInjector(new MouseActionModule());
System.out.println(injector.getProvider
(MouseActionListenerFactory.class).get());
System.out.println(injector.getProvider
(MouseActionListenerFactory.class).get());

However, if your original code is complete, and all the provider does
is to create a new instance of MouseActionListenerFactoy, remove the
provider completely:

public class MouseActionModule extends AbstractModule {
@Override
protected void configure() {
bind(MouseActionListenerFactory.class).in(Singleton.class);
}
}

public static void main(String []args){
Injector injector = Guice.createInjector(new MouseActionModule());
System.out.println(injector.getInstance
(MouseActionListenerFactory.class));
System.out.println(injector.getInstance
(MouseActionListenerFactory.class));
Reply all
Reply to author
Forward
0 new messages