Should Guice Providers be annotated with #Singleton? My justification: if the Provider is providing an object to other Singleton classes and the object itself is relatively expensive to create, then wouldn't it make sense to use a Singleton Provider that constructs the expensive object in its #Inject-marked constructor, store it as a member and just return that already-saved global variable in the getter? Something like this:
#Singleton
public class MyProvider extends Provider<ExpensiveObject> {
private ExpensiveObject obj;
#Inject
public MyProvider() {
/* Create the expensive object here, set it to this.obj */
}
#Override
public ExpensiveObject get() {
return obj;
}
}
Update
Let me clarify a little bit more here. This is not about whether I should be using #Singleton or .in(Singleton.class). This has to do more with the "caching" of the created object.
Let's say that object creation required multiple RPCs to complete, such as deserializing JSON or making HTTP requests. This could take quite some time. If I am going to use this Provider to inject into classes multiple times, then doesn't it make sense to only create such an object once?
Also note that I must be able to use a Provider because I need to be able to inject into the Provider.
If your question is whether you should create scoped provider bindings, or if you should cache instances in your providers manually, then really, do not try to be smarter than Guice :) You really do not want to do anything more than just create your expensive object in get() method. Simple test case:
public class MyProvider implements Provider<String> {
public String get() {
System.out.println("Called MyProvider.get()");
return "abcd";
}
}
public class MyModule extends AbstractModule {
protected void configure() {
bind(String.class).toProvider(MyProvider.class).in(Singleton.class);
}
}
Injector injector = Guice.createInjector(new MyModule());
String abcd1 = injector.getInstance(String.class); // Prints "Called MyProvider.get()
String abcd2 = injector.getInstance(String.class); // Prints nothing!
// Or, if you want, comment out above two lines and try the following:
Provider<String> abcdProvider = injector.getProvider(String.class);
abcdProvider.get(); // Prints "Called MyProvider.get()"
abcdProvider.get(); // Prints nothing
You see, because the message was printed only once, MyProvider.get() method was called only once too, exactly because String is bound in singleton scope.
The key concept to understand here is that providers and bindings are not separate entities. With every binding there is an associated provider (when you create plain bindings with to(), an implicit provider is created for you). This can easily be observed from getProvider() method signature - it accepts Class<T> or Key<T> for actual class you want to get, not for the provider you have bound. When you create a binding to specific provider, you do not configure this provider, you configure the binding. Guice is smart enough to take scopes into account even if you use explicit providers, so you just do not need to reinvent the wheel and roll out your own singleton.
If your question is specifically about usage of #Singleton annotation (as opposed to bind() DSL), then I don't know whether its presence on provider class gives any effect, but given that you should use bind().toProvider() to bind to this provider anyway, I don't think that it really matters. Just use in() method, it will certainly work.
Please beware that there is a major difference between binding your provider to the Singleton scope by using .in(Singleton.class) and using the #Singleton annotation on your provider class.
In the first case the get() method is only called once and the result will be stored in the Singleton scope.
In the second case the provider instance is just created once but the get() method is called for each injection point in your application.
If you use this approach it would be wise to manually cache your expensive object. But there is no point in doing so, really. Just use the first approach and you are fine.
You could even combine the two strategies, e.g. by annotating the provider with #Singleton and bind the provider result to request scope by using .in(RequestScoped.class). Without the annotation your provider will be instanciated for each request, which might matter if it stores stateful data.
This is just for clarification as some reader may stumble upon your question and may think the two approaches are sematically equal.
Yes, in principle, but then in this instance, you could do away with the provider altogether and just create ExpensiveObject as an eager singleton. It'll only be instantiated once when the injector is created, and that single instance will get injected everywhere it's required.
Related
The method getById is located in an Abstract class named AbstractCachedResult.
public abstract class AbstractCachedResult<T extends BaseResource> {
#Cacheable(value = "dynamicName")
public T getById(String id){
//program logic
}
}
Many other service classes will be inheriting from this class. For ex :
public class UserService extends AbstractCachedResult<User> {
//program logic
}
Since I am setting the #Cacheable(value = "dynamicName") in the abstract class I wouldn't be able to know the type of the class that was returned by the method. I need to be able to get the name of the class dynamically so that for each method invocation from its inherited class the correct cache is used.
I have came across another post. Here they are passing the entity class name as a parameter which I cannot do. I need to get the type of the returned data dynamically so that I could us the #Caching annotation which is the #2 soluton. Is there a way to do this?
Arguably, the simplest and most obvious solution, especially for maintainers, would be to override the getById(:String) method in the subclass, like so:
public class UserService extends AbstractCachedResult<User> {
#Cacheable("UserCache")
public User getById(String id) {
super.id(id);
}
// additional logic
}
Alternatively, you might be able to implement a "custom" CacheResolver (see doc and Javadoc) that is able to inspect the class generic signature of the (target) subclass.
Finally, under-the-hood, Spring's Cache Abstraction is implemented with Spring AOP. For real, low-level control, it should be possible to write custom AOP Interceptor not unlike Spring's default CacheInterceptor (Javadoc). Your own AOP Advice could even be ordered relative to the Cacheable Advice, if needed.
Honestly, I think the first option I presented above is the best approach. Not every service class may need to cache the result of the getById(:String) operation. Caching really depends on the transactional nature of the data and how frequently the data changes.
Use your best judgement.
I have two data source class, LocalDataSource and RemoteDataSource. In DataRepository, I need both the classes but on need basis. I don't want to inject both the classes in DataRepository constructor. Instead want to overload constructor with single data source class. How to implement this with dagger?
To directly answer the question: Dagger supports one #Inject constructor at most. You can use a #Provides method to call any constructor or factory method you'd like, but if you want Dagger to manage your dependencies it will only read the single constructor you specify with #Inject. That said, that's not quite the right solution here in any case.
If your class needs a LocalDataSource or a RemoteDataSource, and you don't know which one until runtime, inject a Provider<LocalDataSource> and Provider<RemoteDataSource> (or Lazy<LocalDataSource> and Lazy<RemoteDataSource>). These objects are inexpensive Dagger-implemented abstractions over your LocalDataSource and RemoteDataSource constructors, which Dagger automatically allows you to inject: For any T available in your graph, you can inject Provider<T> and Lazy<T> (or even Provider<Lazy<T>>, as described in the documentation).
In this way, Provider and Lazy can help you avoid creating either DataSource instance until you know which one you need.
The difference between them is that Lazy<T> will locally cache the object instance, acting like a field in your class. Provider<T> will always consult your Dagger Component, which will in most cases will return you a newly-allocated object unless you've applied a scope like #Singleton. If your objects are expensive to construct, Lazy is a good choice, since you'll only request one instance across the lifetime of your consumer; if they are cheap to construct, then you might even choose to use a Provider within a method and letting your object be garbage-collected as soon as it is no longer needed.
Of course, as Steven and AlphaOne point out in the comments, you might also consider a design where your DataRepository consumer accepts an arbitrary DataSource that you or Dagger can provide. This generally makes sense, as DataSource is likely a useful interface and DataRepository might not need to know implementation details of the source it consults. However, if you need to handle an arbitrary source specification at runtime, at some point you'll still need to inject both a #Local DataRepository and #Remote DataRepository (assuming you've created #Qualifier annotations #Local and #Remote), and at that point it makes even more sense to use a Provider/Lazy instead of creating both DataRepository objects and their respective DataSources.
public interface SomeObject {
void process();
}
public class SomeObjectImpl implements SomeObject {
public SomeObjectImpl() {
...
}
#Override
public void process() {
...
}
}
public class AnotherObject implements SomeObject {
private SomeObject object;
#Override
public void process() {
if (object == null) {
object = new SomeObjectImpl();
}
object.process();
}
}
I think it's the Singleton pattern because it states that a class must ensure that only a single instance should be created and a single object can be used by all other classes. In the example, when SomeObject is null an instance is created as required.
However, it also looks like the Proxy pattern is used, because SomeObject is the proxy.
Is this code really using both patterns? Or is the Proxy pattern used only?
The Singleton Pattern's purpose is to ensure that only one instance of the singleton class ever exists.
Does the given code ensure that? No, because nothing prevents you from creating as many instances as you like from the two classes SomeObjectImpl and AnotherObject (by just invoking their default constructor).
Hint: See the Wikipedia page on Singleton Pattern for implementation examples in different languages... and once you've seen how to create singletons – then forget about using them in real code, ever – as it's the best way for creating untestable software ⚡ and having global variable(s) ⚡ gluing everything together.
The Proxy Pattern's purpose is to control the access to an object or to provide some additional functionality upon accessing an object.
Does the given code look something like that? Yes.
The two classes SomeObjectImpl and AnotherObject implement the interface SomeObject. That interface (in terms of the Proxy Pattern) represents the Subject providing some action, i.e. the process method. The SomeObjectImpl class is then the acutal implementation; the RealSubject (as named by the Proxy Pattern). While AnotherObject class simply delegates to the actual implemenation SomeObjectImpl, i.e. it's a Proxy.
Given that code, the Proxy's purpose (or additional functionality) is to cache an instance of SomeObjectImpl for subsequent process calls. This makes sense when the object creation is a costly operation. For example, when the process method implementation requires the setup of some external resources or requires "big" upfront memory allocations, ...
I'm new to Generics and the Singleton pattern in Java. I have the following questions:
Is a Generic class compatible with the Singleton Pattern, namely having a static instance?
If so, I have the following Generic class that I want to convert to a Singleton. What is the best practice?
(Beginner question) Is there a good way to de-generify an instance of the class in runtime? passing the class as parameter in getInstance()?
class GenFooSingleton <T>
{
private T t;
// Prevent direct instantiation
private GenFooSingleton(T o){
this.t = o;
}
private static GenFooSingleton INSTANCE = null;
// Returns the single instance of this class, creating it if necessary
static synchronized <T> GenFooSingleton<T> getInstance(T tClass)
{
if (INSTANCE == null)
{
INSTANCE = new GenFooSingleton<>(tClass);
}
return INSTANCE;
}
}
Edit
My use case of a Generic with Singleton:
1. Why Generic?
First let's say I have the the following Singleton Repository for one type of data to begin with, the following example is from what I learned in the googlesamples/android-architecture
class FooRepository implements FooDatasource
{
private final FooDatasource local;
private final FooDatasource remote;
Map<String, Foo> mCahcedItems;
// Prevent direct instantiation
private FooRepository(FooDatasource remote, FooDatasource local){
this.remote = remote;
this.local = local;
}
private static FooRepository INSTANCE = null;
// Returns the single instance of this class, creating it if necessary
public static synchronized FooRepository getInstance(FooDatasource remote, FooDatasource local)
{
if (INSTANCE == null)
{
new FooRepository(remote,local);
}
return INSTANCE;
}
// implement CRUD methods
#Override
public Flowable<List<Foo>> getFoos(){
// Update the mCahcedItems with the list of Foos
// return a list of Foos and syncing between the local and remote datasources...For brevity the bunch of Rxjava implementation is omitted.
}
#Override
public Flowable<Optional<Foo>> getFoo(){
// Update the mCahcedItems with Foo
//...
}
}
But I can see I would have to create repository for each data type. (Foo, Baa, Daa, etc) where the CURD logic is essentially the same and each instance. So naturally I'm thinking of making the repository a Generic one.
2. Why Singleton?
Without using the Singleton pattern, each new instance would start a complete new reload the in-memory cache, which means new local database queries. In developing for mobile and memory constrained devices (Android Apps), that would amount to unnecessary and I/O calls each time the device changes configuration/rotation. The mere thought of that just flags a huge performance problem that I would have to deal with. Therefore, I think A globally accessible single instance that is only lazily instantiated is a plus.
My attempt
So I set out to create generic versions of both the Repository and Datasource interface, and have each data type provide the concrete implementation when they implement the Datasource interface, like below:
class FooDatasource implements GenericDatasource<Foo>
{
//...
}
class BarDatasource implements GenericDatasource<Bar>
{
//...and so on and so forth
}
Update
My current approach is a singleton pattern with Generic instances can be better managed with Dependency injection using Dagger 2, for both Java and specifically Android dev.
Is a Generic class compatible with the Singleton Pattern, namely having a static instance?
No, it won't work like that, static fields exist only once, static inheritance doesn't exist in Java. But there are many different ways to implement a singleton.
If so, I have the following Generic class that I want to convert to a Singleton. What is the best practice?
Don't do it. Singleton is an antipattern, mainly because it's horrible for testing purposes. Instead, use a container (Spring, Guice, EJB etc.) to manage singletons for you, making sure only one instance exists. Start by reading about the Dependency Inversion Principle and Inversion of Control.
(Beginner question) Is there a good way to de-generify an instance of the class in runtime? passing the class as parameter in getInstance()?
Yes, passing the class to getInstance would actually make this a bit nicer, especially if you use a class-to-instance-Map internally (Guava has such a type)
Since the singleton pattern tries to guarantee only one living instance of a given class at any time, it's not very compatible with the idea of a versatile class that can accept or produce different results depending on its current generic type. For generics to be any useful, you need to be able to create different flavors of the same type (usual exemple: a List of String and a List of Integer)
N/A
If you are passing a parameter to the getInstance of a singleton, then you are not really wanting a singleton but a factory. A singleton can only be non parameterized, or else the first call freezes the context.
Do not abuse of singleton. They are the first pattern you may try to implement, because it's the first in every book, but it's almost always at least useless, at most a performance bottleneck and a bad design decision (not very OO)
EDIT:
you assumption that each new instance couldn't share the same cache is basically wrong, for two reasons:
not using a Singleton does not forces you to use several instances of the same type. It just allows you to do so, as well as enabling inheritance (which the singleton simply cann't). If you use Spring and a singleton-scoped bean (the default), then your repository exists only once in memory - even if it does not implement the singleton pattern as described in the books - and is shared between all consummers (thus only one cache). This can be accomplished without spring too, just use some kind of factory or registry.
caching with an hashmap in your class is a bit fishy, too. Caching is an implementation detail and you should not try to implement it in this way (you will end up eating the whole memory quite easily, at least, use WeakHashMap instead - or the Guava version, using CacheBuilder). You could also declare your cache as static so it will only exist once in memory. Modern applications treat caching as an aspect, like transactions for example. It should not leak to your code. For example, look at ehcache, redis, terracotta, etc. they all implement the JSR-107 and are configured directly on your method prototype, with some annotation (#Cacheable, etc.). Ho and caching usually goes to the service layer - you do not cache the state of the db, you cache the responses sent to the users after processing of the business logic (even if this rule is not absolutely strict)
The singleton also has a very big problem: it is directly responsible to instantiate the object, that is, direct use of the new keyword. This is a pain, as you can not change the concret type of the implementation at runtime (for testing purpose, or any other use). Look at the factory/factory method pattern to see a better way to change the type at runtime.
What you can do is having an abstract base class, generified, that your concret dao will extend (but those will not be generic). Something like this:
abstract class AbstractDao<ID, T> {
private Class type;
protected AbstractDao(Class type) {
this.type = type;
}
void save(T entity) {
// save an entity
}
T get(ID pkey) { /* get an entity */}
...
}
public class DaoX extends AbstractDao<Long, X> {
DaoX() {
super(X.class)
}
/* Empty! or only methods applicable for X */
}
public class DaoY extends AbstractDao<Integer, Y> {
DaoY() {
super(Y.class)
}
/* Empty! or only methods applicable for Y */
}
In this case you are not duplicating any code.
I have Guice-injected objects which have two lifecycle methods bind() and unbind(). The method bind() is called automatically after the object is instantiated by Guice using following annotated method:
#Inject
final void autoBind() {
bind();
}
What I want to do is to call the method unbind() on the old (current) object before a new instance of the object is created by Guice. How do I do that?
Thanks in advance!
First of all, I would not advise that you just annotate arbitrary methods with #Inject. Keep it to constructors, and occasionally for optional injection and/or field injection.
What you are trying to do does sound a bit weird, and I'm not sure it's exactly what you want. Can you please provide more background on what you're trying to do because maybe a different approach is better. There are definitely some concerns here with thread safety and how you manage references.
Based on what you described, an approach like what #meverett mentioned would probably work. If the objects you have are Foos, it would look something like this.
// Later on be sure to bind(Foo.class).toProvider(FooProvider.class);
final class FooProvider implements Provider<Foo> {
private final Provider<Foo> unboundFooProvider;
private Foo currentInstance;
#Inject FooProvider(#Unbound Provider<Foo> unboundFooProvider) {
this.unboundFooProvider = unboundFooProvider;
}
#Override public Foo get() {
if (currentInstance != null) {
currentInstance.unbind();
}
currentInstance = unboundFooProvider.get();
currentInstance.bind();
return currentInstance;
}
}
NOTE that your #Unbound Foo provider would generate Foos without invoking any special methods. The regular FooProvider keeps track of state and deciding when to bind() and unbind() the instances. Please be careful with how you manage multiple instances and use them with multiple threads.
Also, just to be clear: I'm using #Unbound since the methods you want to invoke are called bind() and unbind(). I'm not using "bound" in the Guice sense.
Also note... off the top of my head I'm pretty sure Providers are treated as singletons, so maintaining state like this will work. If it didn't, you could obviously just create a level of indirection with some kind of singleton factory (but that shouldn't be necessary).
Previous responses address other concerns nicely, so to just answer the question:
Netflix introduced governator in github in 2012 to "enhance Google Guice to provide ... lifecycle management". It provides annotations (#PreConfiguration, #PostConstruct, #PreDestroy, and others), classpath scanning & auto binding, and other features. Bootstrapping is straight forward.
I suppose you could have a provider that keeps a reference to the current object. When you call get on the provider it would unbind the last object, construct the new one and save the reference to it.
though I'm not really sure why you would want to do something like this since other objects can in theory still be referencing it