Google-guice: bind all instances of the same class to certain instance - java

I do not have a problem to bind singleton instance to some other instance using #inject.
But, when it comes to binding more instances of one class to some other instance (which is singletone) it refuses to bind it somehow and I'm getting null reference.
My code example is:
public class WebSocketManagerImpl implements WebSocketManager {
#Inject
private FactoryWebSocket factoryImpl;
}
When I create several instances of WebSocketManagerImpl, every factoryImpl field is null pointer.
Am I doing something wrong?

Please use Binding Annotations (https://code.google.com/p/google-guice/wiki/BindingAnnotations). This way you can annotate multiple instances of same class, and then have them selectively injected.

Related

Create an object of a java class whose constructor is annotated with #Autowired

There is a class whose constructor is annotated with #Autowired. I want to create an object of this class without actually passing the constructor parameters and using the default parameters. Can someone tell me how can i create an object of this class?
One of the reasons of using Spring framework is you don't create objects and manage them manually spring does it for you.If you can give some more details example code or something it will help to understand your situation better.
Spring is a dependency injection framework (it does hosts of other stuff as well). So the whole point is not to "create" your own instances and re-use the instances that Spring has created for you.
If you want create object of class whose constructor is marked as #Autowired then still you can create object of that class using normal new java operator.
You can create an object of that class by just marking your field with #Autowired.Spring handles object creation for you.

If I use Spring's #Autowired annotation on a member of a class, can I new up the class?

I have a dependent class B of class A that I want injected into A.
And so I use the #Autowired annotation in class A. But class A itself I create using new keyword and I find that the reference to class B is null.
So if you are using Autowired, must Spring manage class A also?
I mean, is the null reference because I am using new and not letting Spring manage the whole thing?
Yes, the both classes need to be in the same context. Manage by Spring.
You can see an example here.
http://www.mkyong.com/spring/spring-auto-wiring-beans-with-autowired-annotation/
Yes, Spring container should manage objects of class A and B to be able to inject B reference into A.

Do Guice #Singleton have to follow the Singleton design pattern?

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.

Java best way to share an object across other objects without using 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.

Configuring state of mocked object for different scenarios

I've a DAO and a service class. In the service class CapService, I've #Autowired a reference of DAO class CapDAO. The CapDAO class has a private instance field of type int, that has it's value injected from a properties file using #Value annotation.
class CapDAO {
#Value("${someProperty}")
private int expiryTime;
}
class CapService {
#Autowired
private CapDAO capDAO;
}
There is a method - retrieveCap() in the CapDAO class, which retrieves the caps from the database, based on the expiryTime. That method is invoked from another method in CapService class.
The CapService class uses the list returned from DAO method to create another object wrapping that list. And finally it returns that data structure.
Now, I'm testing a scenario using Mockito framework. I've two scenarios. In both of them, I want to invoke method of CapService class, which will get me the object. The list retrieved form database, will depend upon the value of expiryTime in the CapDAO class. And so will the content of the object returned by CapService class method.
In test, I'm invoking the method in Service class, and checking the value returned. Since DAO is reading expiryTime from properties file, both the test scenarios cannot pass with the same configured value. I've to have two differently configured DAO instance to be injected into Service class.
So, my question is - is there any way I can configure the expiryTime in CapDAO class, to create two different instance, or may be in a single instance only, and inject those in CapService based on scenario? No I don't have any setter for expiryTime. Yes, I knwo I can use reflection, but I would like to keep that as my last resort.
Short answer
reflection is easiest possibility, you can simply use ReflectionTestUtil. Note: If you have an interface which CapDAO implements, you need also AopUtils
Long answer
If you don't wanna use reflection, you need separate your context and test to get this work:
// context1.xml
<context:property-placeholder location="classpath:test1.properties"/>
// context2.xml
<context:property-placeholder location="classpath:test2.properties"/>
Then you can define someProperty with some other value in the properties.
personally i will recommend reflection.

Categories