Do classes annotated with #Singleton have to follow the Singleton design pattern?
My guess is that they do not: it is not necessary to have a private constructor, and a static .instance() method, but instead it is Guice that makes sure that only one instance of the class will be instantiated.
Not only are they not required to follow the Singleton pattern, they explicitly should not follow it.
A system that is properly set up with Guice should be creating as few of its own objects as possible, instead letting the framework do all of the object creation. Further, you do not want random classes in your system to be calling .instance() on this static instance, and, finally, you do not want Guice to be creating a static reference in the Singleton class using .requestStaticInjection().
The right thing to do with your #Singleton classes is to just have them be injected into the classes that need that particular dependency.
The difference between a singleton in Guice and the regular singleton has to do with context.
When you're not using Guice you have to manage your singleton yourself. To ensure that there is only ever one instance created you have a private constructor, a static field and methods to access this instance (either a getter or making the field final). This means that the instance is a singleton in the context of the class loader. If you create another class loader and tell it to load your singleton class you can create a second instance.
When the singleton is managed by Guice we replace the private constructor and static field with the #Singleton annotation, telling the injector that it should only ever create one instance of this class and use it anywhere it is requested. Since it is possible to have more than one injector simultaneously (either because you need two completely different contexts or because you're using child injectors) you must not prevent Guice from instantiating more than one instance of your class.
Additionally, since you should rely on Guice to provide the singleton everywhere it is required there is no need for a static field containing the singleton instance since it should never be accessed.
Related
So I'm implementing a Dependency Injection framework into my Java project (Google Guice) and everything is pretty good, I like it but there's a small problem;
I want to make a static instance of my main project's class (where it instantiates the dependencies, etc). But I don't know any method to instantiate it using Guice, I can't instantiate it manually because I'm using DI in the constructor of it (I have objects in the constructor) which means that I am not able to access the class' non-static variables needed to instantiate the class.
I tried using a Provider but I couldn't really understand where to bind it, because I don't want to have an interface for the main class (will if needed).
If you are wanting to mix a static instance of a class with dependency injection, you have somewhat missed the point of dependency injection: you can simply inject the instance of the class.
If you want there to be a single instance of a class for your injector, bind it in #Singleton scope: either:
bind(YourClass.class).in(Singleton.class);
in your module's configure() method, or
#Provides #Singleton YourClass provideYourClassInstance() {
// ...
}
in your module, or
#Singleton class YourClass {
// ...
}
in the actual class declaration.
Then just inject this instance like any other:
class SomeOtherClass {
#Inject SomeOtherClass(YourClass instance) {
// ... Do something with instance, like assign it to a field.
}
}
The point is that SomeOtherClass shouldn't need know anything about the lifetime of instance: it simply doesn't matter whether this is a singleton instance, or every class using it has its own instance.
You can get three different answers here depending on the question.
To directly answer the question in the title (DI with arguments in the constructor), you can mix DI with constuctor arguments by instead injecting a Factory. Though you're welcome to write one manually, Guice can do this for you as assisted injection (see FactoryModuleBuilder), or you can use the equivalent code-generated solution AutoFactory popular through Dagger.
If you're trying to initialize a static class's fields in a Guice application, Guice can do that for you as soon as the Injector is created. Simply call requestStaticInjection in a Module you feed to Guice. This, as Andy Turner pointed out, will cause you to miss out on some of the benefits of Guice: Because you're injecting the instance statically, there's very little opportunity for you to provide replacement implementations in tests or in other class reuse. Guice describes this more in the static injections section of its wiki:
When migrating an application from static factories to Guice, it is possible to change incrementally. Static injection is a helpful crutch here. It makes it possible for objects to partially participate in dependency injection, by gaining access to injected types without being injected themselves. [...]
Static members will not be injected at instance-injection time. This API is not recommended for general use because it suffers many of the same problems as static factories: it's clumsy to test, it makes dependencies opaque, and it relies on global state.
The best overall solution is in Andy's answer: Adapt your application to use DI, which will let it inject the objects that you would otherwise make static.
I have class A which instantiate class B which in turn do same for class C and so on, forming a large tree. I now need to instantiate an object that should be available all across the tree and I don't want to individually inject this object manually in all classes. I don't want to use a static because there could be different instances of class A running concurrently in different thread and this shared object must be unique per thread. I don't have much experience with thread safe operations.
Use Spring to manage the instance. That way you can inject your instance into any class that needs it and, provided the creation of the parent class is spring managed, the injected bean will be populated.
In some more detail, what you can do is define a class.
public class MyBean {
// Add your class details.
}
And ensure that Spring is either scanning its package or you have defined the bean in your applicationContext.xml file like this. The next stage is to inject this bean where you need to, using the #Autowired annotation..
#Autowired
private MyBean myBean;
And on the creation of that class, myBean will be populated with the same instance of MyBean that was initially created.
Advantages
Doing it this way means that your solution scales well. You can inject it anywhere without constantly changing constructors (and when you're creating more and more sub classes and relationships between classes, this is a prime candidate for Shotgun Surgery.
It's always good to learn about technologies that are used in industry.
Managing a single instance of a class using other methods (like the Singleton pattern) is usually a bad idea.
Disadvantages
Spring does a lot more than just inject objects, and you're pulling down a lot of classes to do just this, which will increase the size of your solution, although not significantly.
Extra Reading
Have a look at a basic Spring tutorial to get you going.
Have a look at the different scopes that you can create beans with, in case some of them suit your needs better.
You either need a local reference in the context that you want to use the object or you need a static reference. Since you don't want to use static you need to get a local reference. You can do this by passing the object in in the constructor or by adding a setter method. Then higher up the tree where ever you construct the child node you pass in the needed object.
You can have kind of a "Parallel Singleton" so to say, i.e. instead of having only one instance it will keep as many instances as there are threads, in a hashmap with a thread-related object being the key.
I have query on bean instantiation in spring.
According to the Spring Reference document, in the section 'Instantiating beans", it is mentioned that
" container itself directly creates the bean by calling its constructor reflectively, somewhat equivalent to Java code using the new operator " .
This implies that Spring container uses reflection to create beans.How ever in few scenarios, container also uses static factory method on a class to create a bean. The only case I knew container use static factory method is "WHEN THE CONSTRUCTOR IS PRIVATE".
So my doubt is, since container uses Reflection to create objects, it should be able create objects of classes of even private constructor as well.Why should container rely on static factory method ?
Or are there any other uses of calling static factory method to create beans ?
Thanks in advance. If there is any fundamental understanding required for me, kindly suggest so.
Yes you are right Spring can invoke private constructor if you provide right arguments while defining the bean in configuration. But on question that comes to my mind is why would you do that if that bean is not meant to be instantiated?
It would be the case only say when you have helper class with static method or singleton etc. So it wont make sense to instantiate those classes.
But in your case, it's factory and you might be getting the object back by calling static method (accessing Static method/field doesn't necessarily need Object to access field/method) say getShape and you might be getting different shape based on parameter's that you might supply.
We sometimes need to use a class which was not designed for Spring and need to be instantiated via static factory method and Spring provides us with such possibility.
In my application (standalone), when I need to get some object instance from Guice, I usually do it like this:
injector = Guice.createInjector(new AppModule());
instance = injector.getInstance(MyInterface1.class);
I was wondering:
Why do I need to pass an instance of the AppModule class, and not the module class reference itself, so Guice could instantiate it?
What side-effects should I expect if I keep my AppModule class as a singleton, therefore always using the same instance when calling Guice.createInjector()?
As a side note:
What about the Injector itself? How bad design would it be if I keep just one instance of it somewhere?
Passing an instance to createInjector allows you to configure the module to your liking via constructor parameters. Guice does not mutate the Modules so you could keep them around, but a better practice is what you're already doing: create a single Injector and bootstrap your application from there. As your application grows you'll write more modules and you don't want to manage that complexity yourself.
You shouldn't have to maintain a reference to the Injector because you can always just inject it, although there are a limited number of cases where this is appropriate. It makes more sense to inject the actual dependencies into your class. This makes the dependency hierarchy clear and your code much more testable.
By default a class is singleton or not ..
public class You{
}
public class My(){
public static void main(String a[]){
You you=new You();
}
}
is you object is singleton ..
if it is singleton how to make it prototype ..
if it is prototype how to make a class as singleton..
Thank you in advance..
No, it's not a singleton. You can create multiple instances:
You you1 = new You();
You you2 = new You();
A singleton class enforces only a single instance being created, usually by including a private constructor, and a static method to retrieve the single instance. This can be achieved simply in Java using an enum with only one value.
Then:
if it is singleton how to make it prototype
The term "prototype" has no meaning in Java. EDIT: If you're talking about Spring, prototype is a scope - and it's very Spring-specific.
By default a class is singleton or not .
No that class is not a singleton, as it has a default 0-arg public constructor added by the compiler. So, you can create as many instances as you want for it.
if it is prototype how to make a class as singleton..
I guess, the term prototype you are relating to the scope of bean instances in Spring framework. In Spring, by default all the beans are singleton. To make it prototype, you have to specify scope = "prototype". But I suggest you to learn the basics of Java, before jumping into a framework.
There are various things you must consider for making a class singleton:
Make the class final, so that it can't be extended.
Make all fields private final
Make the constructor private
Use a private static final instance field in that class, and a public static getter which allows the same instance to be shared across application
Save the singleton class from being instantiated while serialization and deserialization.
The best way to achieve all these is to use an enum, with a single constant in it:
enum You {
INSTANCE;
}
By default a class is singleton or not ..
No, you can create multiple instance to a default class.
is you object is singleton ..
No.(See in the link attached ,why it is not).
if it is singleton how to make it prototype ..
Again No, it's not a singleton. It's already a prototype (In your assumtion,non singleton)
if it is prototype how to make a class as singleton..
What is an efficient way to implement a singleton pattern in Java?
And finally:
Official docs on Creating Object's in Java