Welcome to my first article for my genre #WHAT IS?. Today I'll show you how I started to appreciate the concept of Dependency Injection (abbreviation: DI).
My bumpy learning path
During several coding projects at the Unversity, I never enjoyed the power of DI. As we were greenhorn developers none of our project members knew about this pattern. For using class dependencies in our source code we just created the required objects with the new operator. We were happy that our code compiles and runs on our machines. Since we never wrote tests for our code we also never felt the pain of testing business logic while using new several times.
When I first started to write code as an employee for an enterprise application and had to write unit tests for my code. Since then I realized how awful it is to test code where I used new
. While looking at the Java EE codebase and the several @Inject
@Named
@RequestScoped
annotations I was overstrained and never took time to really understand this concept. Somehow I made use of these annotations and was able to enjoy the “magic” of DI. But only after troubleshooting with lots of WELD exceptions.
Switching from Java EE to Spring
As we switched our codebase from Java EE to Spring I wanted to understand what Spring does and why it's an alternative for Java EE. At its core, I realized that Spring is a DI framework and it's like a competitor for Java EE. With Spring I now used @Autowired
instead of @Inject
and had to forget the Java EE annotations. As it was not satisfying for me to just replace some annotations and not knowing how DI works under the hood.
One of my main learning tools was the book Pro Spring 5 where the authors dedicated a whole section for the concept of DI. For a deeper understanding of DI I also purchased the Udemy course Spring Framework 5: Beginner to Guru and got quite good insight into this topic from John Thompson the owner of www.springframework.guru. In one of the videos he cited a quote which is quite accurate for explaining DI:
Dependency injection for five-year-olds
When you go and get things out of the refrigerator for yourself, you can cause problems. You might leave the door open, you might get something Mommy or Daddy doesn't want you to have. Next, you might even be looking for something we don't even have or which has expired.
What you should be doing is stating a need: “I need something to drink with lunch”. Then we will make sure you have something when you sit down to eat. [^1]
After working on the book and the course I can now say that I understand the concept. Furthermore, I can now effectively make use it and have deeper knowledge about it.
Dependency Injection with the Spring Framework
With Spring or every other DI framework, you get an application context that holds your created Beans. This container will also inject the Beans you request in your production code.
The following simple snippet shows an example for creating a service Bean:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Spring will automatically scan all your components and // with the @Service annotation you tell the context that // this class is a service Bean @Service public class SomeService{ public PersonDto getPersonById(Long id){ PersonDto result = new PersonDto(); // ... get the data from database, modify it // and then return it. return result; } } |
The following Java code shows the controller side which is requesting a service bean:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@Controller public class HomeController { private SomeService someService; // you can also omit the @Autowired annotation in the latest // spring version at the constructor @Autowired public HomeController(SomeService someService){ this.someService = someService; } @RequestMapping("/home") public PersonDto getPersonById(@RequestParam("id") String id) { return someService.getPersonById(Long.valueOf(id)); } } |
During the runtime of your application, the context will provide your HomeController
an instance of SomeService
and your controller doesn't have to know about how an instance of SomeService
is created. Furthermore, you don't need the new
operator which makes your code easier to test with e.g. Mockito framework.
If you are facing similar knowledge gaps or never heard of DI, I can highly recommend you to read this book. For those of you who work with Java/Jakarta EE have a look at this tutorial to start using DI in your applications.
Have fun using Dependency Injection,
Phil.