This page contains my notes from the following books:
a) Dependency Injection in Action by Prasanna
b) Learning Google Guice by Hussain Pithawala

Index for Book Dependency Injection in Action by Prasanna:
Chapter 0 - Interesting Links
Chapter 1 - Dependency injection: what's all the hype
Chapter 2 - Time for Injection
Chapter 3 - Investigating DI
Chapter 4 - Building Modular Applications
Chapter 5 - Scope - A Fresh Breath of State
Chapter 6 - More use cases in scoping

Index for Book Learning Google Guice by Hussain Pithawala:
Chapter 4 - Guice in Web Development



Links
- Google Guice Wiki on Github
- FAQs on Guice
- Google Guice Group
- Link to java doc for FactoryModuleBuilder
- In Guice, the default scope is Prototype. In Spring, the default scope of a Bean is Singleton.
- Guice, Dagger, Spring
- Bean scopes in Spring. Official Doc.

Chapter 1: Dependency injection - what's all the hype?

Seeing objects as services
- A central idea in this book is that - of an object acting as a service. Take an email sending service for example. The email itself can be viewed as a message composition service, the internet relays that are routing the email to its destination as delivery agents, and the receiver's inbox as a receiving service.
- Consider the following architecture for the service: EmailMessagingService - Let the three objects responsible for these actions be: Emailer, InternetRelay, RecipientInbox. Each object is a client of the next. Emailer uses the InternetRelay as a service to send email, and in turn, the InternetRelay uses the RecipientInbox as a service to deliver sent mail.
- There's value in decomposing our services into objects. Take the Emailer for example. The Emailer will require a text editor to type-in the email. This logic could be added in the Emailer class itself, but it is better to create a new TextEditor. Pulling this functionality into its own class has the following advantages:
a) Our Emailer is not cluttered with distracting code meant for text manipulation.
b) We can reuse the TextEditor component in other scenarios (say, a calendar or note-taking application) without much additional coding.
c) If someone else has written a general-purpose text-editing component, we can make use of it rather than writing one from scratch
- This principle is important because it highlights the relationship between one object and other objects it uses to perform its function: an object depends on its services in order to perform its function. In this example that we are talking about, the Emailer class depends upon a TextEditor, SpellChecker, and a Dictionary to perform its functions. Hence these 3 classes are the dependencies of the Emailer class. In other words, the Emailer class is a client of its dependencies.
- The dependencies of the Emailer class may have dependencies of their own and this relationship carries on transitively. This composite system of dependencies is known as the object graph.
- Hence we get the following definitions:
a)

Service

: An object that performs a well-defined function when it is called.
b)

Client

: Any consumer of a service. A client calls a service to perform a well-understood function.
c)

Dependency

: A specific service that is required by another object to fulfill its function.
d)

Dependent

: A client object that needs a dependency (or dependencies) in order to perform its function.
e)

Dependency Injection

: DI is the study of reliably and efficiently building such object graphs and the strategies, patterns, and best practices therein.
Pre DI Solutions
- Suppose you were asked to create an Emailer which is composed of a SpellChecker, this might be the first thing that you come up with:
Expand Gist Expand Code Snippet
- But what is the problem with this approach? Suppose you wanted to test that the SpellChecker was in-fact being called when you used the send method to send an email. One way to do this would be to create a MockSpellCheckerand make Emailer use that:
Expand Gist Expand Code Snippet
- But now you cannot use this mock because you cannot substitute the internal spellchecker that the Emailer class has. This effectively makes the Emailer class untestable.
- There is another problem with this approach. You cannot create objects of the same Emailer class with different functionality. For instance, suppose you were writing an email client for the english language, then you would do something like:
Expand Gist Expand Code Snippet
- Now if you wanted to use the same Emailer class for the french language, you would have to create a completely new Emailer class. We need another system where instead of the dependent creating its own dependencies, it has them provided externally.
Construction by hand
- Instead of the constructor of the Emailer creating its own SpellChecker, we can add a method that accepts a SpellChecker.
Expand Gist Expand Code Snippet
- This allows us to substitute the SpellChecker with a version of our own, and thus we can use the MockSpellChecker that we created above to now test the functionality of the Emailer class. Similarly, we can also substitute the SpellChecker with another spell checker easily now.
Expand Gist Expand Code Snippet
- In the above example, we are setting the SpellChecker manually. At the time of construction of the Emailer class, we are manually setting the dependency. Hence, this is also sometimes referred to as construction by hand.
- The above code was an example of setter injection. You can also do a constructor injection by passing in the dependency during the construction of the Emailer class itself. The advantage of following this approach is that it makes the dependency between the two classes explicit. You cannot create an Emailer class without creating a SpellChecker class. And thus it reduces the chances of someone forgetting to set the dependency on the object.
Expand Gist Expand Code Snippet

Problems with construction-by-hand

: The problem with this technique is that the burden of knowing how to create the object graph is placed on the client of the service. In this case, it is the Emailer class that must set up its dependency, SpellChecker, either through constructor or through setter injection. Also, if the same object is being used in multiple places, then you need to repeat the code of wiring together the object in all the places. If you decide to change the dependency graph in the future, you will have to go to all the places and make the change yourself.
- Another problem is the fact that users need to know how object graphs are wired internally. This violates the principle of encapsulation and becomes problematic when dealing with code that is used by many clients, who really shouldn't have to care about the internals of their dependencies in order to use them.
Factory Pattern
- One way of getting around the problem of having to construct the objects in an object graph yourself is to use a Factory Pattern.
Expand Gist Expand Code Snippet
- The most important thing to notice here is that the client code has no reference to spellchecking, address books, or any of the other internals of Emailer. By adding a level of abstraction (the Factory pattern), we have separated the code using the Emailer from the code that creates the Emailer. This leaves client code clean and concise. This becomes even more useful when the object graph of the created object is even more complex.
Expand Gist Expand Code Snippet
- Talking about testing, the Emailer code is still using the same constructor injection it was using previously. So we can still test the Emailer class as we were previously.

Problems with using Factory Pattern

: Testing the internals of the object returned from the factory becomes difficult unless the factory has explicitly provided capabilities to test it. What do I mean by that? This client does not know anything about Emailer's internals; instead, it depends on a Factory. In one of the previous scenarios, we were able to swap out the SpellChecker being injected into the class with a MockSpellChecker of our own. But that will not be possible in this case.
- Another issue is that if you are going with Factory Pattern then you will have to create a new method for every variation of every service. That is a lot of code to test and maintain. If you decided that you wanted to replace the AddressBook with PhoneAndAddressBook, you will have to go through all the methods in the factory and make the substitution. Plus there might be many dependencies that are common across different types of Emailer objects but which you still have to specify separately for each new method that you add to the factory. One way to get around this is to use a 'general' factory that first creates a common version of the object and then use that intermediate object to set any specific fields on it. But this again leads to code that is difficult to test.
Service Locator Pattern
- A Service Locator is also a kind of factory. The way that it works is that you pass in a key to the service locator, and the service locator replies with a fully-formed object that you can use in your code.
- This is what it would look like: Emailer emailer = (Emailer) new ServiceLocator().get("Emailer");
- Since all the locator needs is a key, a Service Locator acts as a factory that can return any kind of service. Compare this to the EmailerFactory class where it was returning only one type of object - namely Emailer.
- The Java Naming and Directory Interface (JNDI) is a good example of a Service Locator pattern. It is often used by application servers to register resources at start time and later by deployed applications to look them up. Web applications typically use JNDI to look up data sources in this manner.
- An example of gettig a different object: Emailer emailer = (Emailer) new ServiceLocator().get("JapaneseEmailerWithPhoneAndEmail");

Problems with using Service Locator Pattern

: Being a kind of Factory, Service Locators suffer from the same problems of testability and shared state. The keys used to identify a service are opaque and can be confusing to work with. The practice of embedding information about the service within its identifier (namely, "JapaneseEmailerWithPhoneAndEmail") is also verbose and places too much emphasis on arbitrary conventions.
Embracing Dependency Injection
- DI is a magical way that takes all the good parts of the above solutions and leaves behind all the bad parts. DI enables testability in the same way as construction by hand, via a setter method or constructor injection. DI removes the need for clients to know about their dependencies and how to create them, just as factories do. It leaves behind the problems of shared state and repetitive clutter, by moving construction responsibility to a library.
- In case of DI, the task of creating, assembling, and wiring the dependencies into an object graph is performed by an external framework known as a dependency injection framework or simply a dependency injector. The control over the construction, wiring, and assembly of an object graph no loger resides with the clients or services themselves. This is also known as the Inversion of Control. EmailMessagingService
- Notice that EmailClient knows nothing about what kind of Emailer it needs or is using to send a message. All it knows is that it accepts some kind of Emailer, and this dependency is used when needed. Also notice that the client code is now starting to resemble service code; both are free of logic to create or locate dependencies.
- This highlights the separation of infrastructure code (meant for wiring and construction) from application code (the core purpose of a service).
Expand Gist Expand Code Snippet
- Footnote about Gin: Guice is also available inside the Google Web Toolkit (GWT), via its cousin Gin. Google Gin is a port of Guice for the GWT, a JavaScript web framework. Find out more here.

Chapter 2: Time for Injection

Constructing objects with dependency injection
- The dependency injector is itself a service like any other. And like any service, it must be constructed and prepared before it can be used. Once the injector has been bootstrapped, we can obtain an object from it for use.
- This is an example of using Guice for injection:
Expand Gist Expand Code Snippet
- Think of Guice as a factory class for Dependency Injectors. Note that in the above example, you are asking Guice directly for an Emailer class. The object graph of the Emailer class requires dependencies SpellChecker and Dict. But you don't have to worry about providing these. Guice can wire-up the fully-formed object for you when you request it. Also note that you had to use the @Inject annotation on the Emailer and the SpellChecker classes in order to get the code to compile properly. If you remove this annotation, from either of the classes, you get the following error: "Could not find a suitable constructor in Chapter2._1_Basics.SpellChecker. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private."
- The @Inject annotation is supposed to tell Guice which constructor to use when creating the object, and consequently what it's dependencies are.
- In this particular line: Emailer emailer = Guice.createInjector().getInstance(Emailer.class); you are doing something similar to what we did in the Service Locator pattern, the difference being now we are using a class type to get an object as the key, instead of directly using a string. In a sense the injector is an automated, all-purpose service locator prepackaged for convenience.
Metadata and injector configuration
- In essence what you did by using the @Inject annotation was configure the injector by telling it which constructor to use and hence what the dependencies of the object are. If you had been using Spring, you would do the same thing by using @Component and @Autowired combination.
- There are multiple ways in which you can configure the injector:
a) Using an XML Configuration File
b) Invoking into a programmatic API
c) Using an injection-oriented DSL
d) By inference; that is, implicitly from the structure of classes
e) By inference from annotated source code
XML Injection in Spring
- When using injection in Spring, we do the following (the other stuff remains common):
Expand Gist Expand Code Snippet
- Here, BeanFactory refers to the Spring dependency injector. The call to getBean() is analogous to the original call to getInstance(). Both return an instance of Emailer. The FileSystemXmlApplicationContext is a special type of BeanFactory. There are other kinds of application contexts available for use as well. They are mentioned on this link on Baeldung.
- The file email.xml contains the configuration required for Spring's injector to provide us with an emailer correctly wired with its dependencies.
Expand Gist Expand Code Snippet
XML to in-code configuration in Guice
- Using an XML configuration is advantageous in the sense that all the configuration can be easily seen in one place which becomes easier when you are working on a large project. You can do the same thing with Guice as well. In the case of Guice, you can do it in two ways. Either by implementing the Module interface, or by extending the AbstractModule class.
- Guice is able to automatically inject Concrete Class with either a public no argument constructor or a constructor with @Inject without any specific defined binding in your module but when it comes to Interfaces you have to define the necessary bindings. Source on SO. This is what the module class would look like with the bindings defined:
Expand Gist Expand Code Snippet
- Note that the config on the main class now changes slightly. Note that we are passing in the module class that we created to the createInjector method. Without this it does not work.
Expand Gist Expand Code Snippet
- If you were doing the same thing using the AbstractModule, this is what the module class would look like. And instead of passing in the new EmailModule() as you did above, you would now be passing in new EmailAbstractModule().
Expand Gist Expand Code Snippet
- Note that you can also pass in multiple modules as args:
Expand Gist Expand Code Snippet
Revisiting Spring and autowiring
- You can use autowire in the config files to configure the Spring injections as well. The config file in that case will look like this. But note that Intellij does not like this and tries to revert to the method above, ie. make the constructor injection explicit.
Expand Gist Expand Code Snippet
- Of course, you can also just entirely ignore the XML configuration, and go directly with annotations. In the setup that you are using, you still included the xml file as well.
Expand Gist Expand Code Snippet
- And the context that we are using to get the beans from is defined as follows:
Expand Gist Expand Code Snippet
- Note that now we have to use the ClassPathXmlApplicationContext, instead of the FileSystemXmlApplicationContext that we used previously above. Note that you also had to add this in Facets in Intellij, because it was giving you a warning. Note the folder structure as well. The reason for highlighting the folder structure is so that you can notice the usage of class path related stuff. See how paths are being used in new ClassPathXmlApplicationContext("email-actual-autowire-config.xml") and <context:component-scan base-package="_1_Basics"/> and relate it to the folder structure being used. The same warning that you get when you add an XML configuration file, you also get when you annotate a java class with @Configuration. Both, XML files and @Configuration are different but equivalent ways of telling Spring how you want to setup the beans. SpringFacets - The three application contexts that were introduced above can be seen here: SpringFacets
Identifying dependencies for injection
- A flat object is an object that has no dependencies of its own.
- In the Guice example that we saw above, there is a single implementation of the EmailerIF that we are using to inject in as a dependency, namely the Emailer class. But we might have multiple implemnetations of the same interface and we may want to conditionally inject different implementations depending on our requirements. For example, on the right side, we have two implementations of the EmailerIF, Emailer and AdvancedEmailer. So when we create an EmailClient, we might might want to choose either of the implementations, Emailer or AdvancedEmailer. So how do you tell your injector which of these two dependencies you want to use? This is the question we will be trying to answer here. SpringFacets
Identifying by String keys
- Suppose that we are using Spring, and we are trying to create the following dependency graph. Emailer requires a SpellChecker, and there are two possible implementations of it - EnglishSpellChecker and FrenchSpellChecker. SpringFacets - Then depending on the type of Emailer that we are trying to create, we can configure the xml as follows:
Expand Gist Expand Code Snippet
- And we create instances of the Emailer as follows: and this will give us a fully-formed french emailer.
Expand Gist Expand Code Snippet

Drawbacks of this method

:
a) A misspelled key that maps to no valid service can be difficult to detect until well into the runtime of the program. If you are working with a statically typed language like Java, this is a poor sacrifice to have to make. These languages are supposed to offer guarantees around type validity at compile time. Ideally, one should not have to wait until runtime to detect problems in key bindings. Intellij does not warn you about these kinds of errors, and they appear only during runtime.
b) In your injector configuration there is no way to determine the type of a binding if all you have is a string key. Without starting up the injector and inspecting the specific instance for a key, it is hard to determine what type the key is bound to. But do note that Intellij does provide you with some level of static checking in order to minimize this kind of issue. For example suppose you passed in an incorrect class Dict_2 instead of Dict, Intellij would give you a compile error.
Expand Gist Expand Code Snippet
Identifying by type
- Since Guice configuration file requires you to explicitly specify the class that you are going to inject, the compile time checking of the classes being injected can be done in Guice configuration as well (just like Spring). This takes care of the point 2 of the drawback we discussed above. Also since there is no name in the form of String being associated with the dependency, there is no scope of mistyping the name and getting a run time error either. This takes care of the point 1 of the drawback.
- All the stuff with the XML configuration that we did in the above section using Spring, we can also do using simple annotations. We make use of the @Configuration and @Bean annotations for this. The objective is still the same - pass in different implementations of the SpellChecker class for the specific implementations for the Emailer. But this time without using XML.
- First we need to define a configuration class that would be equivalent to defining the XML file in the previous approach. The @Configuration annotation indicates that the class can be used by the Spring IoC container as a source of bean definitions. It indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.
- The @Bean annotation tells Spring that a method annotated with @Bean will return an object that should be registered as a bean in the Spring application context. See this link on Tutorials Point for a good explanation. We aren't doing anything special, all we have done is convert the XML bindings into code.
Expand Gist Expand Code Snippet
- And then we can use these beans as follows. We need to register and refresh the context for this reason explained on SO.
- If you had just a single object of a particular type, you could have fetched the object using the type of the object, as we are doing with the EnglishSpellChecker in the below example. For other cases, you would have to fall back to using the String keys instead.
Expand Gist Expand Code Snippet

Drawbacks of this method

:
a) Like we saw, if we use types, we cannot distinguish between different implementations of the same service.
Combinatorial Keys
- Ideally we want something like this: [Emailer.class, "english"]. The type key identifies the service that dependents rely on, in a safe and consistent manner. Its counterpart, the string key, identifies the specific variant that the key is bound to but does so in an abstract manner. However, the String part of the key is still susceptible to typos and errors that we saw previously. We get around this issue by using an annotation in place of a String.
- GuiceTM embodies the use of type/annotation combinatorial keys and was probably the first library to use this strategy.
- Suppose this is the object graph that we are going to create. As we can see in the diagram, FrenchEmailer and EnglishEmailer both require the dependency SpellChecker. But there are two different implementations available: FrenchSpellChecker and EnglishSpellChecker. We want the EnglishSpellChecker to be injected into the EnglishEmailer class and the FrenchSpellChecker into the FrenchEmailer class.
- The way we are going to do this is through the use of annotations. At the point where we are injecting SpellChecker type into the EnglishEmailer for eg., we will annotate that injection with a custom annotation @English that we have created. Then we are going to tell Guice that - hey, whenever you see a dependency that requires the SpellChecker object, and has been annotated with @English, you should inject the EnglishSpellChecker exclusively. In the same manner, we are going to do for the french side as well. SpringFacets Step 1) We create custom annotations that we are going to make use of.
Expand Gist Expand Code Snippet
Step 2) Annotate the injections with the respective annotations:
Expand Gist Expand Code Snippet
Step 3) Tell Guice to inject the dependencies based off of the annotation that we are using:
Expand Gist Expand Code Snippet
Step 4) Get the object that you are interested in from the injector and makes use as required:
Expand Gist Expand Code Snippet
- This might strike you as odd - while the EnglishEmailer does not depend directly on a specific implementation, it seems to couple via the use of @English annotation. Doesn't this mean EnglishEmailer is tightly coupled to English spellcheckers? The answer is a surprising no. To understand why, consider the following altered injector configuration: bind(SpellChecker.class).annotatedWith(English.class).to(FrenchSpellChecker.class);. Here, we've changed the service implementation bound to the combinatorial key [SpellChecker.class, English.class] so that any dependent referring to an @English annotated SpellChecker will actually receive an implementation of type FrenchSpellChecker. There are no errors, and EnglishEmailer is unaware of any change and more importantly unaffected by any change. No client code needs to change, and we were able to alter configuration transparently. So they aren't really tightly coupled.

Chapter 3: Investigating DI

- In this chapter we will look at different injection idioms. We will see why we should favor constructor injection. We will also see when setter injection is favorable and how to decide between the two. Understanding injection idioms and the nuances behind them is central to a good grasp of dependency injection and architecture in general.
Injection idioms
- The key to understanding the differences between setter and constructor injection is to understand the differences between methods and constructors. The advantages and limitations arise from these essential language constructs.

1) Constructor Injection

:
- A constructor's purpose is to perform initial setup work on the instance being constructed, using provided arguments as necessary. This setup work may be wiring of dependencies (what we are typically interested in) or some computation that is necessary prior to the object's use.
- A constructor has restrictions that differentiate it from a normal method:
a) Cannot (does not) return anything
b) Must complete before an instance is considered fully constructed
c) Can initialize final fields, whereas a method cannot
d) Can be called only once per instance
e) Cannot be given an arbitrary name - in general, it is named after the class

2) Setter Injection

:
- In case of setter injection, the wiring takes place after the instance has been fully constructed.
- The setter injection differs based on the DI framework that you are using. In the case of Spring, a setter directly refers to a property on the object and is set via the <property> XML element.
- This is what the class in the case of Setter Injection would look like. Also note that the setters in this case need to be declared as public.
Expand Gist Expand Code Snippet
- And the XML configuration file would look like this. Note that if you misspell the name of the setter, Intellij is smart enough to give you a compile error. Also note that the order in which these setters are called usually matches the order of the <property> tags. This ordering is unique to the XML configuration mechanism and is not available with autowiring.
Expand Gist Expand Code Snippet
- Doing the same setter injection in the case of Guice would look something like this. Recall that for concrete classes dependency in the case of Guice, we do not need to bind them in the AbstractModule. So for this example, we can leave the AbstractModule class empty. Note that we have annotated the methods with @Inject. Interestingly, even if you remove the annotation from the method, the code still works. So the annotations are not mandatory?
- The order in which these setters are called is undefined, unlike with Spring's XML configuration.
- Another thing to keep in mind is that these setters are called by Guice itself, immediately after the constructor has been executed completely. So when you use this object, the object that you get finally is the fully-formed object. At no point do you have to call the setters manually yourself in order to set these dependencies on the object. The framework does that for you automatically like magic. Of course, nothing is stopping you from calling the setters yourself if you want to and set in a different object for these dependencies, but you do not HAVE to. And that is the important thing to keep in mind. All of the injection is happening behind the scenes, without you having to do things like: Amplifier amp = new Amplifier(); amp.setGuitar(new Guitar()); amp.setSpeaker(new Speaker()) etc. before having to use the amp object.
Expand Gist Expand Code Snippet
- But one nice thing is that you do not need the setter naming convention in Guice, so you can rewrite this class in a more compact way.
Expand Gist Expand Code Snippet
- Notice that this new setter now looks very much like a constructor, as in, it does not return anything, it accepts a bunch of dependencies, and it is called only once when the object is created by the injector.
- Guice does not place any restrictions on the name or visibility of setters either. So you can hide them from accidental misuse. In the above example, you could have declared the set up method as @Inject private void setUp(...), and the code would STILL have worked. This is because Guice takes use of reflection, and reflection can do very weird things. But is this a good thing to do, declaring methods as private and using @Inject on top of that? I don't know.

3) Interface Injection

:
- Interface injection is the same as setter injection except that each setter is housed in its own interface. This design is not commonly used. However, some of the ideas behind interface injection form the basis of important design patterns and solutions to several knotty design problems.

4) Method Decoration

:
- When they are called, these methods return an injector-provided value instead of their normal value. This process is called decorating the method and gets its name from the Decorator pattern. It is useful if you want to make a Factory out of an arbitrary method on your object.
- The problem that we are trying to solve is this. We want the Candy class to be wired and created by the injector. Hence, the way that we are manually creating and returning the object is not sufficient.
Expand Gist Expand Code Snippet
- An alternative would be to have the Sugar dependency injected into the Dispenser class, and use that to create the Candy class. But this is also not optimal because we are reusing the SAME Sugar instance for every new Candy that we are creating. What we want is a new Sugar for a new Candy. Besides, Dispenser must know how to construct Candy and consequently is tightly coupled to its internals. Also, Dispenser is now cluttered with the dependencies of Candy.
Expand Gist Expand Code Snippet
- Method Decoration gets around this problem in the following way. First we provide a dummy implementation of dispense in the code.
Expand Gist Expand Code Snippet
- Then the actual impl of the Candy class is done in the XML files as follows. Read more about this approach here on SO. What we have basically ended up doing is injecting a prototype-scoped bean (Candy) into a singleton-scoped bean (Dispenser).
Expand Gist Expand Code Snippet

5) Field Injection

:
- You can also wire dependencies directly into the fields.
Expand Gist Expand Code Snippet
- Annotating fields barley and yeast with @Inject tells the injector to wire dependencies directly to them when BrewingVat is requested. This happens after the class's constructor has completed and before any annotated setters are called for setter injection.
- Without the ability to set dependencies (whether mocked or real) for testing, unit tests cannot be relied on to indicate the validity of code. It is also not possible to declare field-injected fields immutable, since they are set post construction. So, while field injection is nice and compact (and often good for examples), it has little worth in practice.
Choosing an Injection Idiom
- We are going to be comparing the constructor injection and the setter injection idioms as they are the ones that are the most frequently used.

1) Constructor vs Setter Injection

:
- The merits and demerits of using either constructor or setter injection are the same as those for setting fields by either constructor or setters.
- An important practice regards the state of fields once set. In most cases we want fields to be set once (at the time the object is created) and never modified again. This means not only that the dependent can rely on its dependencies throughout its life but also that they are ready for use right away. Such fields are said to be immutable. The basic idea is that once the dependency object graph has been created, the graph is fixed, and no changes can be done to the graph whatsoever.
- If you think of private member variables as a spatial form of encapsulation, then immutability is a form of temporal encapsulation, that is, unchanging with respect to time. With respect to dependency injection, this can be thought of as freezing a completely formed object graph. Constructor injection affords us the ability to create immutable dependencies by declaring fields as final.
- Immutability is essential in application programming. Unfortunately, it is not available using setter injection. Because setter methods are no different from ordinary methods, a compiler can make no guarantees about the one-call-per-instance restriction that is needed to ensure field immutability.
- A second advantage to using constructor injection is that the object becomes fully available for use immediately. I.e. if a dependency were not provided, either in the configuration, or in a unit test, a compiler error would have alerted us to a misconfiguration immediately. Contrast this with a setter injection. Suppose you forgot to add @Inject on a setter, you wouldn't realize that you missed it unless you tried to execute some method on the injected object, ultimately resulting in a NPE (because the dependency was never set by the injector). Similarly, if you were writing tests for a class using constructor injection, you would just have to call the constructor, and would be enough for the setUp(). But in the case of using setter injection, you need to call the constructor, and then separately have to call each of the setters on the object to set the required dependencies before being able to run any of the tests. Not cool.
- One problem with the constructor injection though is that if your object requires multiple dependencies which are of the same type, it is easy to get the order of the dependencies mixed up and end up with a malformed object. The error goes completely undetected. Imagine a case where you have like 8 string args in a constructor. Compare this to if we were using setter injection, and it would have been very easy to give meaningful names to the setters, thus minimizing any chances of such errors.

2) The Constructor Pyramid Problem

:
- When you have different object graph permutations of the same object, the number of constructors can get out of hand, which becomes confusing when it comes to deciding which constructor to make use of.
- Consider the following Amphibian class:
Expand Gist Expand Code Snippet
- Here we require two mutually exclusive constructors that match either profile but not both. Were you to require more such profiles, there would be more constructors, one for each case. All these constructors differ by is the type of argument they take; unlike setters, they can't have different names. This makes them hard to read and to distinguish from one another. Where an object requires only a partial set of dependencies, additional, smaller constructors need to be written, further adding to the confusion. This issue is called the constructor pyramid problem, because the collection of constructors resembles a rising pyramid. On the other hand, with setters, you can wire any permutation of an object's dependencies without writing any additional code.
- If you find yourself encountering the pyramid problem often, you should ask serious questions about your design befor pronouncing setter injection as a mitigant.

3) The Circular Reference Problem

:
- The problem becomes when you are trying to create an object graph that looks like this. The constructor for a Symbiote requires a Host, and the constructor for Host requires a Symbiote. Both of them refer to the same instances of each other. Syntactically, there is no conceivable way to construct these objects so that circularity is satisfied with constructor wiring alone. If you decide to construct Host first, it requires a Symbiote as dependency to be valid. So you are forced to construct Symbiote first; however, the same issue resides with Symbiote. CircularDependencyProblem - This classic chicken-and-egg scenario is called the circular reference problem. The triangle one is more commonly seen in the wild.
- There are two possible solutions to this, using setter or constructor injection. This link on baeldung explains how to solve this issue in the case of Spring.
- Refer this page on Guice docs to read about cyclical dependencies and how to get around them. This SO answer goes into detail about how Guice works to resolve circular dependency issues. This answer on SO explains the scenarios in which Spring creates proxies.


Spring - using setter injection to solve the issue

:
- The setter injection solution is to just switch to setter injection. When the injector starts up, both host and symbiote object graphs are constructed via their nullary (zero-argument) constructors and then wired by setter to reference each other. The drawback of this approach is that the dependencies can now no longer be declared as final.
Expand Gist Expand Code Snippet
- And the XML Configuration file would look like this:
Expand Gist Expand Code Snippet

Spring - using constructor injection to solve the issue

:
- Solving this by using constructor injection requires us to use a proxy object. First we decouple the Host and the Symbiote so that they use interfaces. The concrete classes HostImpl and SymbioteImpl now have dependency on the interfaces instead of the concrete classes. We have introduced a new class HostProxy that implements the same interface that the HostImpl implements. Unlike HostImpl, HostProxy has a zero-dependency constructor. This means we can now carry out the following sequence of steps in order to form the object graph:
a) Construct HostProxy
b) Construct SymbioteImpl using the instance of HostProxy created in step 1
c) Construct HostImpl using the SymbioteImpl created in step 2
d) Call the setter setDelegate on HostProxy by passing in the HostImpl created in step 3 CircularDependencyProblem - (From the gang of four book) Delegation is basically defined as follows: Delegation is a way of making composition as powerful for reuse as inheritance. In delegation, two objects are involved in handling a request: a receiving object delegates operations to its delegate. This is analogous to subclasses deferring requests to parent classes.
- For example, instead of making class Window a subclass of Rectangle (because windows happen to be rectangular), the Window class might reuse the behavior of Rectangle by keeping a Rectangle instance variable and delegating Rectangle-specific behavior to it. In other words, instead of a Window being a Rectangle, it would have a Rectangle. Window must now forward requests to its Rectangle instance explicitly, whereas before it would have inherited those operations.
- This is the same concept that we are also using over here. The HostProxy is supposed to simply delegate the requests that it gets for performing operations on the Host object to the actual implementation of the Host type (HostImpl) that it has saved.
- Question: Well even though the Host hostProxy field on SymbioteImpl has been marked as final, the setDelegate method allows you to change the underlying reference of Host as and when you like. So where is the immutability that was promised? Hmm?
- This is what the code looks like when we are using Constructor Injection in order to solve the circular dependency issue:
Expand Gist Expand Code Snippet
- And this is what the XML Config corresponding to the code looks like:
Expand Gist Expand Code Snippet

Spring - using annotations to solve the issue

:
- You can get Spring to create the proxies automatically by using the @Lazy annotation.
- This is what the code looks like in this scenario:
Expand Gist Expand Code Snippet
- Sice we are using annotations, the XML files are going to look pretty vanilla.
Expand Gist Expand Code Snippet

Guice - using annotations to solve the issue

:
- In the case of Guice, all you need to do is extract the classes to an interface of its own (a step that we have already done) and then bind the classes to their resp. implementation in the Guice module. The Guice injector automatically provides the proxy in the middle. We can also trust the injector to work out the correct order of construction. We don't deal directly with proxies or setter injection or any other infrastructure concern.
Expand Gist Expand Code Snippet
- And the module itself looks something like this:
Expand Gist Expand Code Snippet


4) The In-Construction Problem

:
- One close relative of the circular reference problem that we saw above is where initialization logic requires a dependency that is not yet ready for use. What this typically means is that a circular reference was solved with a proxy, which has not yet been wired with its delegate.
- This example code is building up on the example that we discussed in the circular dependency problem. Since Host has been proxied but does not yet hold a valid reference to its delegate, it has no way of passing through calls to the dependency. This is the in-construction problem in a nutshell. The only recourse in such cases is setter injection.
- Example code here is in Spring using the same config xml file that we used above.
Expand Gist Expand Code Snippet
- The above problem can be solved by just using setter injection instead of constructor injection as follows:
Expand Gist Expand Code Snippet
- But even the setter injection cannot solve this problem if instead of just the symbiote making use of the host, we now have the host making use of the symbiote as well. Idk man. This seems to be working for some reason. I have no idea what is going on. This code is present here on Github. Figure out what is happening I guess...

5) Constructor Injection and Object Validity

:
- If you use setter injection, you require a lot of upfront work in order to make sure that all the dependencies have been injected properly. For instance, suppose we were trying to set up Spring to wire in the following objects:
Expand Gist Expand Code Snippet
- The XML file would look like this:
Expand Gist Expand Code Snippet
- We would have to make sure of a bunch of things:
a) We have to remember to set both of the setters manually by using the property tags.
b) We have an init method defined in the class, that needs to be manually set up as well by using the init-method tag.
c) Objects in Spring are Singletons by default. This means that other multiple threads are concurrently accessing unsafeObject. While the injector is itself safe to concurrent accesses of this sort, UnsafeObject may not be. The Java Memory Model makes no guarantees about the visibility of non-final, non-volatile fields across threads. To fix this, you can remove the concept of shared visibility, so an instance is exposed to only a single thread. We do this by scoping each bean to a prototype. This tells the injector to create a new instance of UnsafeObject each time it is needed. Now there are no concurrent accesses to UnsafeObject. Notice that you are forced to mark both dependencies with scope="prototype" as well. Otherwise they may be shared underneath.
- You were also confused about the order in which the methods would be called:
Inside the UnsafeObject constructor -> Inside the constructor for Shady -> Inside the constructor for Slippery -> Inside the setShady method -> Inside the setSlippery method -> Inside the init method (init method is called only after the setter dependencies have been set)
- We can solve all of these issues in one go by simply using Constructor Injection. There is only one way to construct it, since it exposes only the one constructor. Both dependencies are declared final, making them safely published and thus guaranteed to be visible to all threads. Initialization is done at the end of the constructor. And init() is now private, so it can't accidentally be called after construction.
Expand Gist Expand Code Snippet
The Reinjection Problem
- This problem is about injecting an object that has already been injected once earlier. Reinjection is typical in cases where you have a long-lived dependent with short-lived dependencies. For instance, consider an example of a dialog box that opens up when a button is clicked and accepts some user text. Every time that the user clicks on the button, you would want a new dialog box to be created, so that the text that was input the previous time does not show.
- Consider the following example. Granny is given one apple when she comes into existence. Upon being told to eat(), she consumes that apple but is still hungry. The apple cannot be consumed again since it is already gone. In other words, the state of the dependency has changed and it is no longer usable. Apple is short-lived, while Granny is long-lived, and on each use (every time she eats), she needs a new Apple.
Expand Gist Expand Code Snippet
- One solution to the problem would be the method decoration solution that we saw above. There we were also returning a prototype-scoped bean from a singleton-scoped bean. We could use the same thing here as follows. But this belies our original object graph (of Granny depending on an Apple) and more importantly is difficult to test. One alternative to this solution is using the Provider pattern that we are going to look at next.
Expand Gist Expand Code Snippet
Reinjection with the Provider Pattern - Using Provider<T>
- Provider pattern is a Factory that the injector creates, wires, and manages. It contains a single method, which provides new instances. It is particularly useful for solving the reinjection problem, since a dependent can be wired with a Provider rather than the dependency itself and can obtain instances from it as necessary.

Using Provider pattern with Guice

:
- This is an example of how we would set the Provider pattern up. Note that no injector configuration apart from this was required in order to set this up. Guice is clever enough to work out how to give you an Apple provider.
Expand Gist Expand Code Snippet
- There a couple of things that we can say about the Providers:
a) A Provider is unique (and specific) to the type of object it provides. This means you don't do any downcasting on a get() as you might do with a Service Locator.
b) A Provider's only purpose is to provide scoped instances of a dependency. Therefore, it has just the one method, get(). Guice provides Providers out of the box for all bound types.
- This is what the Provider interface in Guice looks like. Method get() is fairly straightforward: it says get me an instance of T. This may or may not be a new instance depending on the scope of T. For example, if the key is bound as a singleton, the same instance is returned every time.
Expand Gist Expand Code Snippet

Using Provider pattern with Spring

:
- Spring does not have a Provider class out of the box. But we can create a Provider of our own and use it pretty much in the same way that we did with Guice.
Expand Gist Expand Code Snippet
- And the XML Config will look something like this. Note that we also had to declare the beans.apple as prototype in order for a new instance of Apple to be returned everytime. Note that for the AppleProvider class, we did not have to explicitly tell Spring to wire-in the injector. Spring was able to look at the BeanFactoryAware interface and able to inject it automatically. BeanFactoryAware is an example of the Interface Injection that we looked at above in Interface Injection section.
Expand Gist Expand Code Snippet
The Contextual Injection Problem - Using Custom Factory and @Assisted
- There are some cases where we might want to do partial injection, i.e. have the injector wire up some dependencies for us and provide some dependencies ourselves (for eg. a text that has been entered by the user).
- This SO Link explains Assisted Inject.
- Consider the following example. The Deliverer instance that we want to create has 3 dependencies. Suppose EmailService is supposed to be injected by the injector, whereas the other two dependencies, NewsLetter and date need to supplied by the instance's creator. NewsLetterManager - In such a case, the standard solution is to write a factory that helps Guice build the objects. NewsLetterManager needs an instance of Deliverer in order to send the newsletter to its list of recipients. We cannot create the Deliverer object in the way that we have been doing so far because we need to pass in two args to the object ourselves. We are doing this by creating a factory, DelivererFactory. NewsLetterManger makes the use of DelivererFactoryImpl in order to obtain an instance of Deliverer.
Expand Gist Expand Code Snippet
- Instead of creating a Factory ourselves, we can get Guice to create a factory for Deliverer for us, and then we can just inject the factory whenever we need an instance of Deliverer. This is what the UML looks like in the case when we do use Annotation. The Deliverer class is going to contain the Factory interface. The params passed to the factory interface will be the same params that we want to pass in manually. The corresponding args on the Deliverer constructor itself will have to be annotated with @Assisted and the constructor will have to be annotated with @Inject. This Factory will have to be injected into the NewsLetterManager constructor because that is where we are originally making use of the Deliverer class. We call create there, which goes to the Deliverer.Factory interface, from where Guice automatically creates an implementation of the Factory for us. This is by telling Guice to do so in the GuiceModule class. Guice creates the implementation of the Factory and returns back a fully-formed Deliverer object for us. NewsLetterManager - So much talking. Does it even help clear things up? This is what the code looks like.
Expand Gist Expand Code Snippet
Using @Assisted with multiple args that are of the same type - Using @Named
- Suppose in the above example, we needed to pass an additional String param to the constructor of the Deliverer class called name that would also have to be provided by the instance's creator (just like the date param for exmaple). We would then need to add this param to the Factory interface. But this won't work. If we try to run the code, we will get an error.
- This SO post explains the problem and the solution. Java Doc for FactoryModuleBuilder.
- You get the following error when you do this: String annotated with @Assisted(value="") was bound multiple times. Learn more at this link.
- The types of the factory method's parameters must be distinct. To use multiple parameters of the same type, use a named @Assisted annotation to disambiguate the parameters. The names must be applied to the factory method's parameters and to the concrete type's constructor parameters. Hence the class would now look something like this. The places where we changed the code are commented with // changed here.
Expand Gist Expand Code Snippet
Similar functionality in Spring as @Assisted?
- The following two links on SO discuss couple of ways in which this could be achieved:
a) Is it possible and how to do Assisted Injection in Spring?
b) Partial auto-wire Spring prototype bean with runtime determined constructor arguments
- Here I am following a slightly different approach compared to the above two links, but one that we had done previously in the Provider approach for Spring here. The same BeanFactoryAware method is being used to create a Factory that can form the Deliverer object for us consisting partially of dependencies injected from the container, and runtime values added by us.
Expand Gist Expand Code Snippet
@Provides annotation vs the Provider class
- Guice @Provides Methods vs Provider Classes?
- @Provides vs toProvider binding
Flexible partial injection using the Builder Pattern
- // TODO:
- Refer the Gang of Four book for the Builder pattern. Refer the text for this.
Injecting objects in sealed code
- // TODO:
- Goes over how you can use the Adapter Pattern to inject dependencies into third-party code??

Chapter 4: Building Modular Applications

Understanding the role of an object
- An object is:
a) A logical grouping of data and related operations
b) An instance of a class of things
c) A component with specific responsibilities
- An object is all these things, but it is also a building block for programs. And as such, the design of objects is paramount to the design of programs themselves. Classes should have a specific, well-defined purpose and stay within clearly defined boundaries. Each object has its area of concern. Good design keeps those concerns separated.
Separation of concerns
- Earlier we laid down the principle: separating infrastructure from application logic so that logic that dealt with construction, organization, and bootstrapping was housed independently from core business logic. If you think of infrastructure as being orthogonal to application logic, then separating the two can be seen as dividing horizontally.
- Similarly, logic dealing with different business areas can be separated vertically. Checking spelling and editing text are two core parts of any email application. Both deal with application logic and are thus focused on business purpose. However, neither is especially related to the other. In other words, separating logic by area of concern is a good practice. CircularDependencyProblem
Perils of tight coupling
- Recall the very first incarnation of Emailer that we wrote:
Expand Gist Expand Code Snippet
- This email service was poorly written because it encapsulated not only its dependencies but also the creation of its dependencies. Following are the problems with this:
a) It prevents any external agent (like the injector) from reaching its dependencies. By preventing any external agent from reaching its dependencies, not only does it prevent an injector from creating and wiring them, it prevents a unit test from substituting mock objects in their place.
b) It allows for only one particular structure of its object graph (created in its constructor). By deciding its own dependencies, Emailer prevents any variant of them from being created. This makes for poor reuse and a potential explosion of similar code, since a new kind of Emailer would have to be written for each permutation
c) It is forced to know how to construct and assemble its dependencies.
d) It is forced to know how to construct and assemble dependencies of its dependencies, and so on ad infinitum.
- When a dependent is inextricably bound to its dependencies, code is no longer testable. This, in a nutshell, is tight coupling. Tight coupling also means that we have opened the door in the iron wall separating infrastructure from application logic - something that should raise alarm bells on its own.
- What is the difference between loose coupling and tight coupling in the object oriented paradigm? on SO.
- What is the point of having every service class have an interface? on SE.
Programming to a contract
- An example of a class with tight coupling. In the following example, if we wanted to search for the startsWith in an ArrayList instead of a HashSet, we would have to change the type of the dependency being passed in into the constructor.
Expand Gist Expand Code Snippet
- An example of implementation of the class with loose coupling. By placing an abstraction between dependent and dependency (the interface Collection), the code loses any awareness of the underlying data structure and interacts with it only through an interface.
Expand Gist Expand Code Snippet
Rebinding Dependencies
- The basic idea is altering dependency bindings at runtime. It refers purely to changing the association of a key to an object graph. This is what enables hot deployment of changes. But there are multiple pitfalls that need to be kept in mind:
a) Once bound, a key provides instances of its related object until rebound.
b) When you rebind a key, all objects already referencing the old binding retain the old instance(s).
c) Rebinding is very closely tied to scope. A longer-lived object holding an instance of a key that has been rebound will need to be reinjected or discarded altogether.
d) Rebinding is also tied to lifecycle. When significant dependencies are changed, relevant modules may need to be notified.
e) Not all injectors support rebinding, but there are alternative design patterns in such cases.
- It encapsulates any infrastructure logic and can be used in place of the original dependency with no impact to client code. A change in the binding is signaled to the adapter(s) via a rebinding notification, and the adapter shifts to the new binding. While this is a robust and workable solution, it is fraught with potential pitfalls and should be weighed carefully before being embarked upon.
- There is a difference between hot-deploy and hot-swap as mentioned in this blog post. This SO answer goes into details about how hot-deploy is done.
- This is a SO answer about how hot-swap works.
Rebinding Dependencies - The Simple Way
- Here we are considering a case where we are using an injector that does not support dynamic rebinding. The problem that we are trying to solve is that there isn't enough knowledge while coding to bind all the dependencies appropriately. In other words, the structure of the object graph might change over the course of the life of the application.
- One very simple solution is to maintain both object graphs and simply flip the switch when you need to move from one object graph to another. Here the method rebind() controls which dependency LongLived uses. At some stage in its life, when the rebinding is called for, you need to make a call to rebind(). The problem with this approach is that we end up mixing infrastructure logic with our application logic.
Expand Gist Expand Code Snippet
- What's really needed is an abstraction, an intermediary to which we can move the rebinding logic and still remain totally transparent to clients. We can achieve this by using the adapter pattern. An adapter is supposed to inherit its adaptee.
Adapter Pattern
- Adapter pattern is used to convert the interface of a class into one that the client is expecting. We achieve this by wrapping the object that has an incompatible interface with an object that implements the correct one.
- // TODO: Add text in detail about what Adapter Pattern is, and how it actually works.
- Adapter pattern on Baeldung
- Adapter pattern on Refactoring
Rebinding Dependencies - Adapter Pattern
- This is how you would use the Adapter Pattern to achieve the same result:
Expand Gist Expand Code Snippet
- And the Guice module would look something like this. Note that we had to declare the DependencyAdapter as a Singleton. This was to make sure that the same DependencyAdapter that is being injected into the LongLived class is the same one on which we are calling the rebind() method in the test class. If you remove the Singleton declaration, then the rebind is called on a different instance of DependencyAdapter, and hence both calls of the compute() method end up being called on the DependencyA instance.
Expand Gist Expand Code Snippet
- Now most of the infrastructure code has been moved to DependencyAdapter. When the rebinding occurs, flag useA is set to false and the adapter changes, now delegating calls to DependencyB instead.
- One interesting feature of this is the use of a Rebindable role interface. The control logic for dynamic rebinding is thus itself decoupled from the "rebinding" adapters. All it needs to do is maintain a list of Rebindables, go through them, and signal each one to rebind() when appropriate. (Question: What?). Rebinding of the key associated with Dependency is now completely transparent to LongLived - and any other client code for that matter.
- Picture, because why not: LongLivedClassStructure

Chapter 5: Scope - A Fresh Breath of State

What is Scope?
- Scope is a way of specifying a context under which a key refers to the same instance. When the scope context ends, the instance which is bound to the particular key is discarded, and is no longer injected in other instances. You are basically telling the injector that a particular key is bound to an object only within a specific scope.
- This has some benefits:
a) It lets the injector manage the latent state of your objects
b) It ensures that your services get new instances of dependencies as needed
c) It implicitly separates state by context (for eg. two HTTP requests specifies two different contexts). This means that code working in a context is oblivious to that context. It is the injector's responsibility to manage these contexts.
d) It reduces the need for state-aware application logic
What is the importance of 'Context' in Scope?
- Consider the following scenario: there are three people in a family. There is one bathroom in which there can be exactly one toothpaste. Each of the three members of the family need to use the toothpaste. Since the bathroom is shared by all of the family members, all the family members end up using the same instance of the Toothpaste. Then in this example, the bathroom is an example of a context. Ignore the details currently, and just try to think on a high-level. In this case, we would say that the Toothpaste is Singleton scoped.
Expand Gist Expand Code Snippet
- In contrast, if each family member had their own bathroom (each with it's own toothpaste), then a new instance of Toothpaste would be available to each family member. In this case, the context under which each object operates is unique (that is, its own bathroom). This is like the Toothpaste having no scope at all. This is referred to as no-scope or prototype scope.
Expand Gist Expand Code Snippet
- No code changes were done between the above two cases. All we did was change the context.
No-scope/Prototype
- In a sense, no-scope fulfills the functions of scope, as it:
a) Provides new instances transparently
b) Is managed by the injector
c) Associates a service (key) with some context
- The first two points are self evident. But the last one is not. It's not even true. It is difficult to point out what is the scope that no-scope represents.
- Consider the example that we looked at above. We saw that we could alter the scopes of the objects without making any changes to the objects themselves. To be more precise, the family.give() sequence looked exactly the same for both the singleton as well as the no-scope setup. In that example, we equated the scope of a toothpaste with a bathroom context, and said that each instance of bathroom gets its own instance of toothpaste. But that is not entirely correct.
- Suppose if Charlie wanted to brush his teeth twice daily. In that case, when we asked for a toothpaste, he would have received a completely new instance of it. So now we would have had three instances of bathrooms, but four instances of toothpastes.
- This means that no scope cannot be relied on to adhere to any conceptual context. No scope means that every time an injector looks for a given key (one bound under no scope), it will construct and wire a new instance.
- You can think of no-scope as a split-second scope where the context is entirely tied to referents of a key.
- This becomes very useful when you are trying to inject dependencies in a long-lived object, like we did in the Granny eating example using Provider Pattern here. There, Apple was no-scoped.
- Guice and Spring differ in nomenclature with regard to the no scope. Spring calls it as the prototype scope, the idea being that a key (and binding) is a kind of template (or prototype) for creating new objects.
- Recall in this section in Chapter 3 where we used prototype instances of the objects.
Singleton Scope
- A Singleton's context is the injector itself. The life of a singleton is tied to the life of the injector. Therefore, only one instance of a singleton is ever created per injector.
- It is important to emphasize this last point, since it is possible for multiple injectors to exist in the same application. In such a scenario, each injector will hold a different instance of the singleton-scoped object. This is important to understand because many people mistakenly believe that a singleton means one instance for the entire life of an application. In dependency injection, this is not the case.
Diagram explanation for Singleton vs Prototype Scope
- In the case of a prototype scoped binding, a new instance is returned by the injector everytime that a new object is requested by using its binding. Because of this reason, prototype does not lend itself to a context.
- On the other hand, in the case of a Singleton scoped binding, we can establish a context quite easily. A singleton's context is the injector itself. As long as the injector exists, the singleton object will exist as well. There is a small subtlety here that the scope is one singleton per injector, not per application. If your application has multiple injectors, each of those injectors will hold a separate/distinct reference of the singleton object. Refer the section on Singleton scope here for details. Singleton_vs_Prototype_LifeCycle
How to decide when to use a Singleton
- If a service represents a conceptual nexus for clients, then it is a likely candidate. For instance, a database connection pool is a central port of call for any service that wants to connect to a database. Thus, connection pools are good candidates for singleton scoping.
- Services that are stateless (in other words, objects that have no dependencies or whose dependencies are immutable) are good candidates.
- In the scenario where there are no states to manage, either of prototype or singleton scopes can be used. Singleton does have some advantages over prototype in these scenarios:
a) Objects can be created at startup (sometimes called eager instantiation), saving on construction and wiring overhead.
b) There is a single point of reference when stepping through a debugger.
c) Maintaining the lone instance saves on memory (memory complexity is constant as opposed to linear in the case of no scoping)
- Remember the singleton litmus test: Should the object exist for the same duration as the injector?
Singletons in Practice: Keys are bound under scope, not object or class (Spring example)
- The important thing to keep in mind about scoping is that a key is bound under a scope, not an object or class. This is true of any scope, not just the singleton.
- This is how we would create Singleton scoped beans in the case of Spring. Note that we can also use two different bean names for the same class. (Using camera.basement and camera.penthouse for the same class SimpleCamera).
Expand Gist Expand Code Snippet
- And then we can make use of the beans as follows. camera.basement and camera.penthouse are declared as prototype, hence we get different instances of the SimpleCamera class that is associated with the beans. But the MasterTerminal class that is injected into the SimpleCamera class is declared as a Singleton, and hence the instance injected into the two classes is the same.
Expand Gist Expand Code Snippet
- But now, what would happen if we defined the two beans, camera.basement and camera.penthouse, as singletons? Note that both beans are supposed to create instances of the SAME class, i.e. SimpleCamera. So would the calls to getBean return the same instance of the SimpleClass?
- We changed the xml so that the two beans are now defined as singletons.
Expand Gist Expand Code Snippet
- And we are running the following test. As you can see, the instance of the SimpleClass that is returned from the injector are different. Despite the SimpleClass being associated with a Singleton key. What does this tell us? This tells us that in the case of an injector, the scope is a concept that is associated COMPLETELY with the key. Not with the class. Not with the object. But with a key. It is the KEY that is bound under a scope. If you ask the injector for an object via it's key, the injector will look at the key, see if it is a singleton or prototype, and based off of that, return either the same object, or a new object. There is nothing stopping you from having a completely different key for the same class. The injector does not care about the class. If a key is bound to Singleton, injector can allow multiple instances of the class. But it will allow only ONE instance associated with the key that will be shared with all the dependents.
Expand Gist Expand Code Snippet
- In fact, the same class can also be bound to both Singleton and Prototype. Consider the following xml configuration.
Expand Gist Expand Code Snippet
- And the test class becomes this:
Expand Gist Expand Code Snippet
Singletons in Practice: Keys are bound under scope, not object or class (Guice example)
- The same thing we can do in Guice as well. Consider the simple way first where we have the following Guice Module setup.
Expand Gist Expand Code Snippet
- And the classes making use of the module would look like this. BasementCamera and PenthouseCamera require instances of Camera that is declared as prototype in the Guice Module. Hence, everytime that we construct a new BasementCamera and PenthouseCamera, a new instance of Camera would be injected into it.
Expand Gist Expand Code Snippet
- When two instances of prototype key are being injected into the same constructor, they are still different instances. Consider the following case. BasementFloor requires two instances of the object bound to the [Camera, Basement] key. Both the instances will be different since the [Camera, Basement] key is bound to the prototype scope.
Expand Gist Expand Code Snippet
- Similarly, in this case all four fields of Building receive different instances of Camera even though only two keys are present.
Expand Gist Expand Code Snippet
- This is opposed to the following class, ControlRoom, which has four fields that refer to the same instance of MasterTerminal but via four references.
Expand Gist Expand Code Snippet
- But now, (to recreate the example we saw in Spring above), let us consider the following Guice Module setup. We have two keys defined: [MasterTerminal, RoofMaster] and [MasterTerminal, BasementMaster]. Both of these keys will return an instance of MasterTerminalImpl when injected. Both of these keys are also defined as Singleton. This means that the object associated with each of [MasterTerminal, RoofMaster] and [MasterTerminal, BasementMaster] keys will be unique.
Expand Gist Expand Code Snippet
- Now we make use of the keys in the following test. [MasterTerminal, RoofMaster] and [MasterTerminal, BasementMaster] keys are bound to the same class declared as Singleton. But the instances that are returned by either of the keys are different. Any dependents of [MasterTerminal, RoofMaster] see the SAME SHARED instance. But any dependents of [MasterTerminal, BasementMaster] see a DIFFERENT SHARED instance.
Expand Gist Expand Code Snippet
- To reiterate, it is very important to distinguish that a key, rather than an object, is bound under a scope. Singleton scoping allows many instances of the same class to exist and be used by dependents; it allows only one shared instance of a key.
- This is different from the conventional "Singleton Design Pattern" that we see being used in books which defines a more absolute singleton in the sense that there can always be exactly one instance of a class in an application. This is often considered as an anti-pattern.
The Singleton Anti-Pattern
- As mentioned above, there is a difference between singleton scope, a feature of DI, and singleton objects (or singleton anti-patterns).
- Singleton objects are shared even between injectors and can cause a real headache if you are trying to separate modules by walling them off in their own injectors.
- Singleton objects bad, singleton scoping good. Singleton objects make testing difficult if not impossible and are antithetical to good design with dependency injection. Singleton scoping, on the other hand, is a purely injector-driven feature and completely removed from the class in question.
- Singleton scope is thus flexible and grants the usefulness of the Singleton antipattern without all of its nasty problems. SingletonAntiPattern
Domain-Specific Scopes - The Web
- Goes over request-scoped objects and session-scoped objects.
- TODO.

Chapter 6: More use cases in scoping

Defining a custom scope

Chapter 4: Guice in Web Development

Defining a custom scope