While designing a service class should it be singleton in java? Generally DAO is made singleton, so should the calling Service class be made singleton also?
IMHO yes, services should not hold state and should therefore be made singleton.
Singletons are bad, if you develop them. If you are using dependency injection, let the DI container handle the singleton nature of your Service object. If you are not using dependency injection, use a static method instead of a singleton.
Classic example of bad:
public class HootUtility // singleton because developer was a goofball.
{
...
public void blammy(...) { ... }
public HootUtility getInstance() { ... }
}
... somewhere in the code.
HootUtility.getInstance().blammy(...); // This is silly.
Better implementation of the above:
public class HootUtility // Not a singleton because I am not a ______. (fill in the blank as you see fit)
{
// You can limit instantiation but never prevent instantiation.
// google "java reflection" for details.
private HootUtility()
{
throw new UnsuppotedOperationException();
}
public static void blammy(...) { ... }
}
... somewhere in the code.
HootUtility.blammy(...);
If you have a service interface that has an concrete implementation, use a dependency injection framework to inject the implementation (DI frameworks include: spring and guice).
Edit: If I was using spring, I would choose singleton scope (the default).
No
Actually I believe you shouldn't care about it while design. Like #DwB mentioned DI framework should do this job. Furthermore I believe no scope ("prototype") should be default and I don't see anything bad if somebody will create it itself.
Also that issue can be simplified by modularization and separating service interface and implementation like best practices told as to do.
Related
Say I have a library project which provides a class MyService.
I'd like clients to be able to instantiate MyService as a singleton and at the same time, I'd like the library to be able to access that singleton internally.
Now I can do the standard MyService.getInstance() sort of thing, but that doesn't lead to a very testable code if my library has MyService.getInstance() calls all over the place.
Perhaps any classes in the library that need an instance of MyService can take in MyService as a constructor parameter:
class MyTestableClass(val myService: MyService) {
// Now this class can be unit tested with a mock/fake MyService
}
But at some higher level in the library I'm still going to have to pass MyService.getInstance() to this class.
Is there a standard pattern to accomplish this? Basically I want the client to be able to instantiate MyService as a singleton and also have the library able to access that instance internally, while having the ability to swap out the singleton instance with a mock/fake for unit testing.
I wouldn't say there is a single standard way of achieving this. But here is a approach I used for some libraries in the past.
In Kotlin one possibility to provide the singleton for you is to make use of the lazy delegate. Alternatively you can use an object instead.
public interface SingletonTarget {}
internal class SingletonClassImpl: SingletonTarget {}
public val mySingleton: SingletonTarget by lazy { SingletonClassImpl () }
// or
public object SingletonObjectImpl: SingletonTarget {}
Both can be combined with constructor injection easily.
public fun interface BookFlight {
operator fun invoke(): Unit
}
internal class BookFlightService(private val service: SingletonTarget): BookFlight { ... }
You can provide instances of your functions using factories. This might also be the right place to "glue" your singleton to the library functions.
public fun BookFlight(): BookFlight =
BookFlightService(mySingleton) // or SingletonObjectImpl
I have the necessity to provide the correct Bean implementation at runtime.
The common interface:
public interface MyInterface { ... }
The implementations:
#Named("one")
class MyInterfaceImpl1 implements MyInterface { ... }
#Named("two")
class MyInterfaceImpl2 implements MyInterface { ... }
#Named("three")
class MyInterfaceImpl3 implements MyInterface { ... }
Notice these classes are package-private.
I then wrote a #Produces method:
#Produces
#Singleton
MyInterface getMyInterface(
final Instance<MyInterface> myInterfaceImplementations,
final Configuration configuration) {
// Might be one, two or three.
final String parameter = configuration.getString("value");
return myInterfaceImplementations.select(new NamedLiteral(parameter)).get();
}
Is this the correct way to go, or is there a better solution?
Your solution would work fine, here are my 0.02$ just to make sure you intended it that way:
What Nikos Paraskevopoulos meant in his comment is that your are effectively creating four beans to inject one. MyInterfaceImpl1, MyInterfaceImpl2, MyInterfaceImpl3 are all legitimate beans for injection anywhere in the app. If these beans are heavy, creation may take some time, also the ability to inject them anywhere might not be intended? And then there is your producer method - the fourth bean - which I assume is ultimately the only one you are after.
Secondly, the three implementation beans have different scope from the producer method. If they are eligible for injection, in your case it seems logical that they share same scope perhaps?
Thirdly, using #Singleton. I would also advice for #ApplicationScoped, there is no harm and no overhead by having a proxy. You won't be able to tell the difference and can easily avoid some unpleasant surprises with CDI singleton (which doesn't behave like EJB singleton).
I think a more elegant solution would be to let the CDI do all the magic ;-)
Something like:
import javax.enterprise.inject.spi.CDI;
#Produces
#Singleton
MyInterface getMyInterface(final Configuration configuration) {
// Might be one, two or three.
final String parameter = configuration.getString("value");
Set<MyInterface> candidates = CDI.current().getBeanManager().getBeans(parameter);
return ( candidates.size()>0 ? candidates.get(0) : null);
}
You could also use the alternate signature of getBeans() signature to play with qualifiers when looking for a particular impl of your interface:
cfr https://docs.oracle.com/javaee/7/api/javax/enterprise/inject/spi/BeanManager.html#getBeans-java.lang.reflect.Type-java.lang.annotation.Annotation...-
I have an existing class named Legacy which is mostly written in old school singleton pattern. Now I want to introduce a new field to it and I would like to use Guice. Legacy itself is not Guice controlled, it is used by another Service class (inside the Service class, it calls the getInstance() of Legacy class to retrieve the Legacy object right now), and that Service class is been created using Guice injector.
public class Legacy {
public synchronized static Legacy getInstance() {
if(sInstance == null) {
sInstance = new Legacy();
}
return sInstance;
}
private Legacy() {
legacyObj = LegacyField.getInstance(); // get a singleton
}
private static Legacy sInstance;
private LegacyField legacyObj;
private NewField newObj; // this is the new dependency I would like to add using Guice
}
What I tried is that I tried to put method Inject into Legacy class
#Inject
public void setNewField(NewField newObj) {
this.newObj = newObj;
}
And in the module file of the Service, I bind the NewField object, but when I run the program, it throwed a NullPointer exception. So the inject doesn't work. Any idea of how to make NewField inject into my program but keep the current old-school singleton paradigm and not changing too much about everything else?
EDIT
There are a least three solutions below and I don't quite know which is the best or are they equivalent.
I just found another solution:
// put in the module
bind(Legacy.class).toInstance(Legacy.getInstance());
In this example, your module itself, not Guice, takes responsibility for obtaining a Legacy instance, then asks Guice to always use this single instance to fulfill all Legacy injection requests.
But according to the javadoc
When the Injector is created, it will automatically perform field and method injection for this instance, but any injectable constructor on Legacy is simply ignored. Note that using this approach results in "eager loading" behavior that you can't control.
Though only slightly cleaner than Thomas's answer, you can configure the injection of your Singleton from within your Module using requestInjection or requestStaticInjection.
// In your Module:
requestInjection(Legacy.getInstance()); // for an instance field, or
requestStaticInjection(Legacy.class); // for a static field.
The docs on the wiki warn about the downsides, though:
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.
Here is a somewhat hackish solution.
In the bootstrapping of your application,
may be in method public static void main(String[] args),
you should already have code similar to this:
Injector injector = Guice.createInjector(yourModule);
At this place add the following line:
injector.injectMembers(Legacy.getInstance());
By doing so, all the #Injects in your Legacy singleton
should be resolved.
See also the javadoc of Injector.injectMembers.
I have modifiers such as protected, private and private transient. I am using manual wiring.
I need to use setter injection. Which all variables do I need to wire?
This depends on YOUR needs, not on the needs of Spring.
Because you have setters, then I recommend to make the variables private.
transient would only be taken in account when you serialize this class (the call it must implement the Serializabe interface), but this is highly unusual, so I would not add transisient as long as the class is not Serializabe
Dependency Injection is a software design pattern that implements inversion of control for resolving dependencies. Dependency injection means giving an object its instance variables.
It's like making the class independent of the implementation details of other services (e.g.) that it uses.
e.g.
public class MyClass{
private OtherService os = new OtherServiceImpl();
...
}
In the above code, MyClass is dependent upon OtherServiceImpl. Let's say, in future we realize that OtherServiceImpl does not suffice all of our requirements, or there is another service MuchBetterServiceImpl which is provided by different vendor which helps us.
Now, if we modify MyClass to use MuchBetterServiceImpl as
private OtherService os = new MuchBetterServiceImpl();
We would need to re-comiple and re-test MyClass again.
But with coming in of Autowiring and mocking tools we can make MyClass independent of implementation details of OtherService.
public class MyClass{
#Autowired
private OtherService os ;
...
}
For your particular case, this can be achieved as
public class MyClass{
private OtherService os ;
public OtherService getOs(){
return os;
}
#Autowired
public void setOd(OtherService pOs){
os=pOs;
}
...
}
Whatever way is it done Setter/Constructor it is providing de-coupling the two classes.
Now, to spring it does not matter if you are autowiring what type of fields. As the responsibility of spring is to find a suitable implementation and plug it in your class.
Spring uses reflection to do this linking. And setters should be public/accessible.
It doesn't matter what is the access modifier of your field.
refer this and this questions. for more details.
Coming to your question: What variables do you need to wire: Preferably all the services, controllers, Daos or any other components that you need to decouple should be auto wired.
I'd like an injected instance of an object to know the name of the class that is requesting its injection. I'm aware that this kind of violates the entire concept of dependency injection, but it seems like a valid use case for supporting useful logging. Is this possible with Guice?
Example:
class InjectorAware {
#Inject
public InjectorAware(Class injectorClass){
System.out.println("I was injected into a "+injectorClass.getCanonicalName());
}
}
class NeedsInjectorAwareField {
#Inject InjectorAware injectorAware;
}
When NeedsInjectorAwareField gets injected, the console would print "I was injected into a somepackage.NeedsInjectorAwareField"
Guice actually already injects a java.util.logging.Logger for you that already is customized with the name of the class it's injected into. Not sure how it's done, but you might be able to borrow the technique used from the Guice source...or just use the Logger directly.
UPDATE: this appears to be the point of the Guice source responsible for this behavior. You might be able to borrow the technique somehow, I'm not sure.
It is not possible using only Guice and they wont allow it.
http://code.google.com/p/google-guice/issues/detail?id=27
Not sure if you could do it only with Guice, but it wouldn't be too hard to make it work through the injected constructors.
public interface InjectorAware {
void setInjector(Object injectingInstance);
}
public class Foo {
#Injected
public Foo(InjectorAware injectorAware){
injectorAware.setInjector(this);
}
}
That said. Not sure it's a good idea.
I know it's an old thread, but for those folks who are still trying to solve this problem, have a look at https://github.com/raner/loginject