Book Image

Java 9 Dependency Injection

By : Nilang Patel, Krunal Patel
Book Image

Java 9 Dependency Injection

By: Nilang Patel, Krunal Patel

Overview of this book

Dependency Injection (DI) is a design pattern that allows us to remove the hard-coded dependencies and make our application loosely coupled, extendable, and maintainable. We can implement DI to move the dependency resolution from compile-time to runtime. This book will be your one stop guide to write loosely coupled code using the latest features of Java 9 with frameworks such as Spring 5 and Google Guice. We begin by explaining what DI is and teaching you about IoC containers. Then you’ll learn about object compositions and their role in DI. You’ll find out how to build a modular application and learn how to use DI to focus your efforts on the business logic unique to your application and let the framework handle the infrastructure work to put it all together. Moving on, you’ll gain knowledge of Java 9’s new features and modular framework and how DI works in Java 9. Next, we’ll explore Spring and Guice, the popular frameworks for DI. You’ll see how to define injection keys and configure them at the framework-specific level. After that, you’ll find out about the different types of scopes available in both popular frameworks. You’ll see how to manage dependency of cross-cutting concerns while writing applications through aspect-oriented programming. Towards the end, you’ll learn to integrate any third-party library in your DI-enabled application and explore common pitfalls and recommendations to build a solid application with the help of best practices, patterns, and anti-patterns in DI.
Table of Contents (14 chapters)
Title Page
Copyright and Credits
Packt Upsell
Contributors
Preface
Index

IoC containers


So far, we have talked about the code or framework that plays the role of dependency provider. It can be any custom code or full-fledged IoC container. Some developers refer to it as a DI container, but we will simply call it a container.

If we write custom code to supply dependency, things get smoother until we have just a single level of dependency. Take the scenario where our client classes are also dependent of some other modules. This results in chained or nested dependencies.

In this situation, implementing dependency injection will become quite complicated through manual code. That is where we need to rely on containers. 

A container takes care of creating, configuring, and managing objects. You just need to do configuration, and the container will take care of object instantiation and dependency management with ease. You don't need to write any custom code such as that we wrote while implementing IoC with factory or service locator patterns.

So, as a developer, your life is cool. You just give a hint about your dependency, and the container will handle the rest and you can focus on implementing business logic.

If we choose containers to set dependencies for our Balance Sheet module, the container will create the objects of all dependencies first. Then, it will create an object of the Balance Sheet class and pass the dependencies in it. A container will do all these things silently and give you the object of the Balance Sheet module with all dependencies set in it. This process can be described with the following diagram:

In conclusion, the following are the advantages of using containers over manual code to manage dependency:

  • Isolating the process of object creation from your code and making your code more clean and readable.
  • Removing object wiring (setting dependency) code from your client module. The container will take care of object wiring.
  • Making your modules 100 percent loose coupling.
  • Managing the entire lifecycle of the modules. This is very helpful when you want to configure the objects for various scopes, such as request, session, and so on in application execution.
  • Swapping out the dependency is just a matter of configuration—no change is required in the code.
  • It is a more centralized way to handle object life span and dependency management. This is useful when you want to apply some common logic across the dependencies, for example, AOP in Spring. We will see details about AOP in Chapter 6Aspect-Oriented Programming and Interceptors.
  • Your module can benefit from advanced features that ship with containers.

Spring, Google Guice, and Dagger are some of the IoC containers available today for Java. Starting from Enterprise Edition version 6, Java introduced Context Dependency Injection (CDI), a dependency injection framework in Enterprise Edition. It's more or less similar to Spring's annotation-based DI implementation. Out of all the preceding containers, Spring is the most popular and widely used IoC container today.