I have read several articles and tutorials on Guice (3.0), and now have a few lingering questions before I can "tie it all together".
// 1. Binds via public, no-arg "ServiceImpl()" ctor?
bind(Service.class).to(ServiceImpl.class);
// 2. Every client-side request for a Service instance returns the same
// ServiceImpl instance?
ServiceImpl impl = new ServiceImpl(...);
bind(Service.class).toInstance(impl);
// 3. Every client-side request for a Service instance returns the same
// SINGLETON ServiceImpl instance?
ServiceImpl impl = new ServiceImpl(...);
bind(Service.class).in(Scopes.SINGLETON).toInstance(impl);
// 4. Should this be a call too bindConstant() instead of toInstance()
// instead? If so, how/why?
Integer timeout = 1000 * 60; // 60 seconds
bind(Integer.class).named(Names.named("TIMEOUT")).toInstance(timeout);
So my questions, as implied by the code snippet above:
When using to(...), I assume the public no-arg ctor is used, and a new instance is returned every time?
Per #2 above, is the same impl instance used for ever Service.class request, or is a new one returned?
Same as #3 above, but now with Scopes.SINGLETON specified.
Is the above code OK or should I be using bindConstant()? If so, how/why?
Under what circumstances should I be using so-called provider methods? I sort of understand the example on that page, but am now choking when it comes to finding a real-world use case for them in my code.
Either the public no-argument constructor is used, or an #Inject-annotated constructor (that would be recommended). A new instance is returned every time, unless you specify a scope on ServiceImpl (either by a later bind(ServiceImpl.class).in(...) line or an #Singleton annotation on ServiceImpl.
In this case, the same impl instance is used for every injection of Service
That is a compile error, for good reason -- you can't specify a scope on a toInstance binding.
bindConstant() should be used for things like configuration parameters that are primitive or String types. For more information, see this answer.
#Provides methods are simply a shorter way of writing Provider<>s. If you don't have a need for them, don't use them. They should generally be used if creating an object is more complicated than a simple constructor call.
Related
I'm a fairly experienced programmer but I'm fairly new to Guice and I'm not sure what the best practices are. Here is my possibly flawed understanding so far, please point out if I use incorrect terminology, question follows after:
Classes with a (public) no arguments constructor or an #Inject-annotated constructor (there may be only one such constructor) do not need to be explicitly bound/provided in the module. Though in the latter case, of course, the constructor parameters may need to be explicitly provided unless they can also be auto-provided by the same rule.
When instances of such classes are (automatically) provided, this can always be thought of as being done in injector.getInstance(...) fashion – #Inject-annotated members (like say injected private fields in the class, see my Car example) will also be injected and not left null.
The above two facts(?) partially solve the problem that one can not explicitly bind/provide an instance with #Inject-annotated members, since one can not create an instance inside a provider using injector.getInstance(...) and so the #Inject-annotated members will be left null.
The remaining problem case is when the constructor requires one or more parameters to be given during creation, the values of which cannot be known up front and therefore cannot be injected.
The solution generally seems to be to provide/inject a factory with a parameterized create method to create the instances when and as needed, but this could only be done using new, which does not work in general – what if the class contains #Inject-annotated members itself? Constructing the class with new will leave those should-be-injected members null-valued.
Here is sample code:
class Car {
#Inject
private Engine engine;
...
public Car(final String cannotBeInjected) {
...
}
}
How would I make Car (or a Car factory) injectable and still allow for an Engine instance to also be injected? A possible solution is to just assign the cannotBeInjected value via some setter after creation, but this just doesn't seem elegant.
I've seen a class declared with its only constructor being annotated with #Inject.
And I don't see the one constructor being called anywhere in the entire project.
So two questions:
<1> What does #Inject mean? (What does it do? Why is the constructor being annotated with it?)
<2> As mentioned, the constructor never gets called directly, does that have anything to do with the fact that it is annotated with #Inject?
Google Guice is a dependency injection library that allows you to construct objects simply by declaring relationships between them. Objects are constructed as they are demanded to construct other objects. You can also implement abstract classes or interfaces with different implementations by configuring Guice, which makes it very useful for running or testing your code.
#Inject annotates constructors and methods that determine what an object needs to be initialized. There are also a lot of other annotations that determine how Guice works. But simply annotating objects isn't enough; you also have to configure them with Guice bindings.
Here's a really simple example (from one of my applications). I have a MySQLDataTracker that requires a MysqlConnectionPoolDataSource:
public class MySQLDataTracker extends ExperimentDataTracker {
#Inject
public MySQLDataTracker(MysqlConnectionPoolDataSource ds) {
....
}
}
Note that MySQLDataTracker extends ExperimentDataTracker, an abstract class that can be implemented several ways. In my Guice bindings I declare that
bind(ExperimentDataTracker.class).to(MySQLDataTracker.class);
This declares that whenever I want an ExperimentDataTracker, a MySQLDataTracker will be constructed. I also need to make sure that the requisite object for constructing this is available, so I declare a provider:
#Provides #Singleton
MysqlConnectionPoolDataSource getMysqlCPDS() {
return (some thingy I construct...);
}
This says that there should only be a single connection pool data source. It also means that when I try to get an instance of ExperimentDataTracker, Guice has everything it needs to construct it. If I didn't have the above, it would throw an error.
ExperimentDataTracker tracker = injector.getInstance(ExperimentDataTracker.class);
However, it doesn't stop here. Other things depend on the ExperimentDataTracker, so it's used in turn to inject other objects. At the top level of my code there is actually only one call to getInstance, which makes Guice construct pretty much everything. I don't have to write the new statement anywhere.
I'm a big fan of Guice after seeing how it reduced the need for me to initialize a bunch of objects in order to initialize other objects. Basically I just ask for the object I want, and poof! it appears.
I have a class like this -
class Messages
{
...
LinkedList<String> inputs;
LinkedList<String> outputs;
...
}
Normally, I would initialize inputs and outputs in the constructor -
public Messages()
{
inputs = new LinkedList<String>();
outputs = new LinkedList<String>();
}
However, I want to achieve the same result using spring configuration. So what should I put under the following node?
<bean id="Messages" class="com.somename.Messages">
<--- what goes here?
</bean>
When the Spring Container creates the "Messages" bean, will it call the constructor also?
Yes, it will call the constructor. It would be very odd for an IoC container not to call a constructor - it would have to go to some lengths to construct an instance of the object without going through a constructor, and it would almost always be a bad idea.
Of course, you can also initialize your variables as part of the declaration:
class Messages
{
...
private final LinkedList<String> inputs = new LinkedList<String>();
private final LinkedList<String> outputs = new LinkedList<String>();
...
}
I think it's worth mentioning that behaviour for proxied objects can be quite tricky.
Spring is quite complex when it comes to creating proxies. For example, as of Spring 3.2, CGLIB is re-packaged under org.springframework and it will call a constructor at least once to create a proxy.
It can be more than once it seems when we talk about AOP.
At the same time, as of Spring 4.0, the constructor of your proxied object will NOT be called twice anymore since the CGLIB proxy instance will be created via Objenesis.
Objenesis is a small lib used to instantiate an object without calling the constructor.
So, there's not simple yes or no answer. Surely, constructor will be called at some point to instantiate an object regardless of the framework. But in the modern frameworks there are some tricks that help to reduce the amount of constructor calls to a minimum.
Spring will call the constructor. It will also match constructor arguments if there are any.
Here it is explained in detail http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-collaborators
If you just want to initialize without any data than you can do that in constructor as for object creation contrstuctor will be called. If you want to assign the specific data, than you should have setters in your class and need to use them while creating the bean.
I have few questions regarding Java constructors
Can a constructor be private? If yes then in which condition?
Is a constructor a method or not?
If a constructor does not return anything then why we are getting a new Object every time we call it?
What's the default access modifier of a constructor if we do not specify.
Edit
The answers for 1 & 3 are very clear. I'm still not sure about 2 & 4 since I'm getting different answers for them.
Can a constructor be private? If yes then in which condition?
Yes. There are no conditions. Of course, no one except the class itself can call it then.
This is actually a frequent pattern: Have a static getInstance() and keep the constructor private.
There can also be private constructors that the public constructors internally call.
Constructor is a method or not?
Hmm. I say "no". At the very least, it is a "very special kind of" method. In what context exactly? The terminology is less important than what you are trying to do.
If constructor does not return anything then why we are getting a new Object every time we call it.
The new operator returns something (the new instance).
Whats the default access modifier of a constructor.
Same as for methods. Package-private.
If you do not specify any constructor, the class gets a default constructor, which takes no arguments, does nothing except calling the parent constructor and is public.
Yes, in any case. However, if all constructors for a class are private, that means that the class cannot be directly instantiated. You will need to use something like the Factory Pattern to create instances of the object.
Yes, the constructor is a method.
A better way to think about it is that the new operator returns the object and in the process of creating the object, calls the constructor. Another way to think about it (although this is only a way to think about it, it isn't technically correct) is simply that the return type is implied by convention. A good place to read more about this is to read about new in the context of C++. The constructor's role is not to create the object but rather to initialize the memory contained within the object.
Default access for a constructor in Java is package private just like any other method. (One such source: http://www.javabeginner.com/learn-java/introduction-to-java-access-modifiers and from the horse's mouth: http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
Yes, constructors can be private. This is done when you want tighter or alternate control over instance creation such as with factory methods or with a pattern such as a Singleton.
It is a method but it is not called directly. It is a special type of method invoked on your behalf when you create a new object.
Constructors don't return anything, they create new objects.
The default is package private. So public to any class within the package but not visible to code outside of the package.
Thoughts on Tomcat performance and scalability: This is a highly variable situation based on your server hardware and types of requests and of course the quality, efficiency and memory footprint of the code serving each request.
Your lower bound on concurrent requests was 500. Consider that you probably want to create a thread for each request and given a 1MB stack per thread you're looking .5 GB just for thread stack space. And this is before heap memory and the performance overhead of allocating that many threads. I think that if need to handle that many requests at a time you might want to consider a more heavy duty server like JBoss.
A constructor can be declared private for any class.
A constructor is a special method that returns an instance of the class it belongs to, therefore you do not need to specify a constructors return type.
Package private is the right answer as pointed out below.
Yes -- factory instance singletons often use this pattern, to force users to init their class via static factory method.
Yes, it's a method
Because that is what a constructor does - it constructs. (it's assumed the result of construction will be returned)
same as methods
With regards to your Tomcat question, it depends on which version of Tomcat, which IO model it's using (e.g., NIO versus historical network IO modules), and your configuration. Single Tomcat's can process hundreds of requests at a time, although the concurrency is tune-able (each request will be handled by a distinct thread or thread from a pool).
The default access modifier of a constructor is CLASS ACCESS MODIFIER,
If a class is public , then access modifier of a constructor is public. If the class is default , then constructor is also default.
Constructor can be created as a private in any case.
Constructor is a special type of method which can be automatically called when we
are creating object for the corresponding class.
Constructor does not contain any return values. It just create new objects. Should not provide any return type for constructor.
The default access specifier of the constructor is public
Yes.
Yes.
because a constructor is called by new. What returns the object is the new, the constructor simply sets up the internal state.
Public.
Please explain the use of the interface Supplier(in Guava) with a suitable example .
The Supplier interface is simply an abstraction of a no-arg function that returns a value... it is a means of getting some instance or instances of an object. Since it is so general, it can be used as many things. Jared explained how the Multimaps factories utilize it as a factory for creating a new instance of a Collection of some type for values.
Given the simplicity of the interface, it also allows for some very powerful decoration of a Supplier's behavior by wrapping it in another Supplier that alters its behavior somehow. Memoization is one example of that. I've used the Suppliers.memoizeWithExpiration method myself as an easy way to make it so some data will only be read from a server at most once in a given period of time.
I'd also recommend taking a look at Guice and how the Provider interface is used in it. Provider is exactly equivalent to Supplier and is central to how Guice works.
Provider allows users to define a custom way of creating new objects of a given class. Users can write a get() method which can execute whatever code is needed to create a new object, so they aren't limited to having Guice use constructors alone to create objects. Here, they are using it to define a custom factory for new instance of an object.
Guice allows injection of a Provider of any dependency. This may return a new instance every time get() is called or it may always return a single instance or anything in between, depending on how the binding the Provider represents is scoped. This also allows for "lazy instantiation" of dependencies... the Provider gives a class a means of creating an object without needing to actually create the object ahead of time. An instance of the object does not need to be created until when, and if, get() is called.
As indicated above, Providers form the basis of scoping in Guice. If you take a look at the Scope interface, you'll notice its single method Provider<T> scope(Key<T> key, Provider<T> unscoped) is defined in terms of Providers. This method takes something that creates a new instance of an object (the Provider<T> unscoped) and returns a Provider<T> based on that which applies whatever policy the scope defines, potentially returning some cached instance of the object rather than creating a new one. The default NO_SCOPE scope simply passes along the unscoped provider, meaning a new instance will be created each time. The SINGLETON scope caches the result of the first call to unscoped.get() and thereafter returns that single instance, ensuring that everything that depends on the singleton-scoped object gets a reference to that single object. Note that the Provider returned by the SINGLETON scope's scope method does essentially the same thing as the Supplier returned by Suppliers.memoize (though it's a bit more complicated).
The main reason we included Supplier in Guava was to support the Multimaps methods that generate arbitrary Multimaps, such as
public static <K,V> Multimap<K,V> newMultimap(Map<K,Collection<V>> map,
Supplier<? extends Collection<V>> factory)
The Supplier creates a Collection that holds all of the values for a given key. The Multimap uses the Supplier whenever you store a key-value pair with a key that's not already in the Multimap.
It's a way to provide an indirect object. You may want to provide another object each time Supplier.get() is called.
For example, i have a singleton class called SmtpMailSender, which takes a hostname for the smtp server. However, the hostname can change at runtime, so instead of taking a String hostname, it takes a Supplier<String> hostname.
Another example use of Supplier:
http://javawayoflife.blogspot.com/2010/06/unit-test-and-new-date.html
Another great use of the class is decoupling - if a component only uses another to obtain a value, do not depend on the concrete implementation, but on this interface.
Anyway, there is some example code here: http://www.slideshare.net/tfnico/google-guava
See the Suppliers class and I guess the methods there will somehow answer your question.