When to Use Constructor-based and Setter-based DI in Spring?


In this article, we will discuss the most important topic that is when to use Constructor-based and setter-based DI in Spring-based applications.

Let's first define Constructor-based and setter-based DI with an example.

Constructor-based dependency injection

Constructor-based DI is accomplished by the container invoking a constructor with a number of arguments, each representing a dependency.

In the below diagram, the highlighted part shows the Constructor-based dependency injection.

Setter-based dependency injection

Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or no-argument static factory method to instantiate your bean.
The following example shows a class that can only be dependency-injected using pure setter injection. This class is conventional Java.
In the below diagram, the highlighted part shows the setter-based dependency injection.

When to Use Constructor-based and setter-based DI in Spring?

From spring Framework documentation, Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. Note that use of the @Required annotation on a setter method can be used to make the property a required dependency.
Which of these DI methods is better purely depends on your scenario and some requirements. The following best practices may provide a guideline:
  1. Use constructor-based DI for mandatory dependencies so that your bean is ready to use when it is first called. 
  2. When your constructor gets stuffed with a large number of arguments, it's the figurative bad code smell. It's time to break your bean into smaller units for maintainability. 
  3. Use setter-based DI only for optional dependencies or if you need to reinject dependencies later, perhaps using JMX. 
  4. Avoid circular dependencies that occur when a dependency (say, bean B) of your bean (bean A) directly or indirectly depends on the same bean again (bean A), and all beans involved use constructor-based DI. You may use setter-based DI here. 
  5. You can mix constructor-based and setter-based DI for the same bean, considering mandatory, optional, and circular dependencies. 
In a typical Spring application, you can see dependencies injected using both approaches, but this depends on the scenario, considering the preceding guidelines.

Conclusion

Use the DI style that makes the most sense for a particular class. Sometimes, when dealing with third-party classes for which you do not have the source, the choice is made for you. For example, if a third-party class does not expose any setter methods, then constructor injection may be the only available form of DI.

Related Spring Dependency Injection Articles

1. Guide to Dependency Injection in Spring
This guide provides what is dependency injection in Spring framework and what are different types of dependency injection supports in Spring with examples (constructor and setter method).

2. Spring Dependency Injection via Setter Example
In this article, we will learn how to use setter-based dependency injection in Spring Applications.

3. Spring Dependency Injection via Constructor Example
In this article, we will learn how to use constructor-based dependency injection in Spring Applications.

4. Spring - @DependsOn Annotation Example
In this article, we will discuss how to use @DependsOn annotation in Spring Applications with an example. The @DependsOn annotation can force Spring IoC container to initialize one or more beans before the bean which is annotated by @DependsOn annotation.

Comments