Dependency Injection In Java made easy (With Lombok)
Dependency Injection is a fundamental design pattern in Java that promotes loose coupling and enhances testability and maintainability of code. Lombok, a popular Java library, simplifies Java development by reducing boilerplate code, such as getters, setters, and constructor generation. When combined, Lombok and Dependency Injection can significantly streamline the development process.
In Java, Dependency Injection is often achieved using frameworks like Spring, which can manage object lifecycles and dependencies. However, the verbosity of Java can sometimes lead to cluttered code, especially when dealing with many dependencies. This is where Lombok comes into play. By utilizing annotations, Lombok can automatically generate constructors, getters, setters, and other common methods, reducing the amount of code developers need to write and maintain.
For instance, in a typical Java application using Spring for Dependency Injection, a class might have multiple dependencies injected through its constructor. Without Lombok, developers would need to explicitly write this constructor along with getters and possibly setters for these dependencies. With Lombok, the @AllArgsConstructor
annotation can be used to automatically generate a constructor with all class fields as parameters, making the code cleaner and more readable.
This synergy between Dependency Injection and Lombok not only makes Java applications more robust by ensuring that components are loosely coupled and easily testable but also enhances the developer experience by reducing the boilerplate code associated with traditional Java development.
How do I add Lombok to my project?
For you to add Lombok to your dependencies, you can add the following lines to your build.gradle or pom.xml files:
If you’re using Maven:
org.projectlombok lombok 1.18.30 provided
If you’re using gradle:
implementation ‘org.projectlombok:lombok’
annotationProcessor ‘org.projectlombok:lombok’
Now, let’s see what dependency injection would look like using Lombok:
Here we have an interface called ExampleUseCase, which is then inherited in ExampleUseCaseImplementation:
public interface ExampleUseCase {
String getExample();
}
import medium.examples.Business.ExampleUseCase;
import org.springframework.stereotype.Service;
@Service
public class ExampleUseCaseImpl implements ExampleUseCase {
@Override
public String getExample() {
return "This is an example!";
}
}
You can see that we have the @Service data annotation in the use case implementation, we do that so spring boot creates a bean for the use case implementation. Because spring boot created a bean for it, we can now use dependency injection in our controller:
import lombok.AllArgsConstructor;
import medium.examples.Business.ExampleUseCase;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@AllArgsConstructor
@CrossOrigin(origins = "http://localhost:3000")
public class ExampleController {
ExampleUseCase exampleUseCase;
@GetMapping
public ResponseEntity<String> getExample(){
return ResponseEntity.ok().body(exampleUseCase.getExample());
}
}
Because we are using Lombok’s @AllArgsConstructor, all we have to do is declare the type of the use case we want to use, in this case its ExampleUseCase and spring boot will automatically search for beans that inherit that use case, which in our case, we only have the one ExampleUseCaseImpl.
There you go!
Now you see how you can use dependency injection in your projects!