Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guice: differences between Singleton.class and @Singleton

Tags:

In Guice, what's the difference between:

// Inside your AbstractModule subclass: @Override public void configure() {     bind(Service.class).to(ServiceImpl.class).in(Singleton.class); } 

And:

@Override public void configure() {     bind(Service.class).to(ServiceImpl.class); }  @Provides @Singleton public ServiceImpl providesService() {     return new ServiceImpl(); } 

Are they both the same? When would you use one versus the other? Thanks in advance.

like image 242
IAmYourFaja Avatar asked Feb 08 '13 21:02

IAmYourFaja


People also ask

What does @singleton do in Guice?

Guice comes with a built-in @Singleton scope that reuses the same instance during the lifetime of an application within a single injector.

What does @singleton annotation mean?

What is singleton? Singleton Pattern in android. A single instance of a class providing a global point of access to itself during the entire application's lifetime. @Singleton annotation in Dagger. A single instance of a class which is unique to a specific component, its access is limited to the scope of the component.

What is the difference between singleton and Dependency Injection?

Dependency Injection is widely considered the cleaner option, but it can get tricky. Singleton is regarded as an anti-pattern by Clean Code advocates, but it's easy, and it works. Still, developers use both patterns to great success.

Why you should not use singletons?

By using singletons in your project, you start to create technical debt. Singletons tend to spread like a virus because it's so easy to access them. It's difficult to keep track of where they're used and getting rid of a singleton can be a refactoring nightmare in large or complex projects.

What is a singleton class?

In object-oriented programming, a singleton class is a class that can have only one object (an instance of the class) at a time.

What is the difference between Singleton and spring Singleton?

Some of the main differences between these 2 are Singleton pattern ensures one instance of a particular class of per class loader. Spring Singleton is “per container per bean”. If you pay close attention, these are entirely different design in terms of how they define singleton.

What is the use of getInstance() method in singleton class?

In a singleton class, when we first time call getInstance () method, it creates an object of the class with name single_instance and return it to the variable. Since single_instance is static, it is changed from null to some object.

What is singleton pattern in Java?

Singleton pattern ensures one instance of a particular class of per class loader. Spring Singleton is “per container per bean”. If you pay close attention, these are entirely different design in terms of how they define singleton.


Video Answer


1 Answers

They are nearly identical. The @Singleton syntax is useful for annotating @Provides methods, or annotating the class itself (though I prefer to keep my scoping annotations inside modules).

The difference lies in which key is marked Singleton, which has less to do with @Singleton versus Singleton.class (or Scopes.SINGLETON, asEagerSingleton, @Singleton class annotations, or toInstance implicit singletons) and more to do with what the default syntax makes easy. For example:

public class MyModule extends AbstractModule {   @Override public void configure() {     bind(A.class).to(AImpl.class).in(Singleton.class);      bind(B.class).to(BImpl.class);     bind(BImpl.class).in(Singleton.class);   }    @Provides @Singleton C provideC() { return new CImpl(); }    @Provides @Singleton D provideD(DImpl dImpl) { return dImpl; }    @Provides E provideE(EImpl eImpl) { return eImpl; }   @Provides @Singleton EImpl provideEImpl() { return new EImpl(); } } 

Above we've bound interface A to class AImpl, and interface B to class BImpl, but the behavior is different:

  • Injecting A will retrieve the same AImpl instance every time.
  • Injecting AImpl will retrieve a different AImpl every time, all of which are different than A's instance.
  • Injecting B will retrieve the same BImpl instance every time.
  • Injecting BImpl will also retrieve that same BImpl instance that B injects.

As you can see, each key is different, and Guice will allow multiple implementation instances if only the interface is bound with Singleton. If you only ever inject A and B interfaces, the behavior looks identical, but if you inject both interfaces and implementations from the same Injector, you may see differing behavior.

Similar logic goes for @Provides methods:

  • Injecting C will always return the same CImpl instance.
  • Injecting CImpl will create a new CImpl every time, unless CImpl has no injectable public zero-arg constructor—then the injection will fail.
  • Injecting D will always return the same DImpl instance.
  • Injecting DImpl will return a new instance every time, and each will be different than the one returned by D.
  • Injecting E will return the same EImpl instance every time.
  • Injecting EImpl will also retrieve that same instance E injects.

This provides some flexibility. Imagine a hypothetical Cache that keeps a certain number of most-recently-retrieved objects, where you want to have @User Cache and @Product Cache both injectable. If you bind(Cache.class).in(Singleton.class), you will have one Cache shared between the objects (and any bare Cache injections), whereas if you bind(Cache.class).annotatedWith(User.class).to(Cache.class).in(Singleton.class) then the annotated key is kept in singleton scope and each object type will have its own cache.

like image 134
Jeff Bowman Avatar answered Sep 21 '22 19:09

Jeff Bowman