This is the third day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021

In this article, I’ll show you how to use Project Lombok as a best practice for dependency injection in the Spring framework.

preface

The Spring framework itself has various ways of performing dependency injection. Flexible choices are the strength of the Spring framework. However, not all di approaches are considered best practices.

Dependency injection

Let’s take a look at some code examples to implement Spring’s various dependency injection approaches. First we have a MyService, which has a sayHi() service in it, and we try to inject it in a different way in Controller.

@Service
public class MyService{
    public String sayHi(a) {
        return "hello Spring."; }}Copy the code

Properties into

@Controller
public class FieldController {

    @Autowired
    private MyService service;

    public String saySomething(a) {
        returnservice.sayHi(); }}Copy the code

With property injection, Spring will inject it through reflection when converting beans. This approach is fine for dependency injection, but at test time you either need to launch the Spring Context or use some Spring utility to perform dependency injection for testing.

We can improve on this by providing setters for private properties. Getters and setters are generally considered best practices in object-oriented programming. It is easy to annotate setter methods to instruct Spring to use setters for dependency injection.

Methods to inject

@Controller
public class FieldController {

    private MyService service;

    @Autowired
    public void setService(MyService service) {
        this.service = service;
    }
    
    public String saySomething(a) {
        returnservice.sayHi(); }}Copy the code

This is an improvement over using private property injection, but there are still people who think it’s too much code.

Constructor injection

When using constructors to inject properties, you must provide the @AutoWired annotation. This is a nice feature that saves us some code. Constructor annotations for dependency injection have been optional since version 4.2 of the Spring Framework.

@Controller
public class FieldController {

    private MyService service;

    public FieldController(MyService service) {
        this.service = service;
    }
    public String saySomething(a) {
        returnservice.sayHi(); }}Copy the code

Constructor-based dependency injection is generally considered a best practice. For a while, I personally favored setter-based injection, but later I switched to constructor-based injection.

There are two main problems with constructor-based injection.

  • The type of our service is concrete. Hard-typed dependency injection is not considered a best practice.
  • The property we are injecting is not declared final, so it is theoretically possible to modify the injected property after instantiation.

Dependency injection best practices

The best practice for dependency injection is to use interfaces, constructors, and final properties.

Best practices service interfaces

public interface BpService {
    String getHello(a);
}
Copy the code

Best practices service implementation

@Service
public class BpServiceImpl implements BpService{
    @Override
    public String getHello(a) {
        return "The Best Hello!"; }}Copy the code

Use Lombok

Next, the reasons to use the Lombok project for dependency injection are:

  • Declare the final property of the interface type
  • Use the args constructor annotations required by Lombok

Lombok Controller

@Controller
@AllArgsConstructor
public class BpController {
    private final BpService bpService;
    public String saySomething(a) {
        returnbpService.getHello(); }}Copy the code

This is a good way to keep the code very clean. When using Spring, you often need several automatically injected properties. When you need to add a bean, you only need properties that are declared final. There is no need to add @AutoWired annotations, no need to add setter methods or constructors.

I’ve been using this approach in everyday coding for a while now. This is definitely a time saver, and the code will become clearer.

summary

In this installment, I’ve shared with you the different approaches to Spring dependency injection, including:

  • Injected via the private property Autowired;
  • Injection via setter methods;
  • Injection through the constructor;

But none of these are best practices, and the best practice I recommend is to use Lombok@AllArgsConstructorAnnotate, and define the bean to be injected as a final property.

Hope to help your development, a “like” is the biggest support for me.