Constructor based dependency injection

Constructor based dependency injection is a type of dependency injection in spring in which dependencies are injected into a class through its constructor.
Constructor dependency injection pattern is a popular way to configure Spring beans. This is in contrast to setter-based dependency injection, in which dependencies are injected into a class through its setter methods.

Constructor based dependency injection example
Constructor based dependency injection in spring is accomplished by annotating a class constructor with the @Autowired annotation.
This annotation tells Spring to inject the dependencies into the class when it is instantiated.
Consider the following example of a simple class that has a dependency on another class

public class User {
  private Role role;

  @Autowired
  public User(Role role) {
    this.role = role;
  }

  public void checkPersmission() {
    role.doSomething();
  }
}

In this example, User class requires a bean or object of type Role.
So, we created a User constructor accepting an object of Role and annotated the constructor with @Autowired.

Remember that for constructor based injection to work, the bean being injected should also be a spring bean. So, in this case, Role class should be created as a spring bean.

We can also inject multiple beans in a single constructor. Below is also a valid constructor injection example

public class User {
  Role role;
  UserDetail detail;

  @Autowired
  public User(Role role, UserDetail detail) {
    this.role = role;
    this.detail = detail;
  }
}

With Spring 4.3, if your class has a single constructor, then you can omit @Autowired annotation.
XML based constructor injection
In above examples, we saw constructor based dependency injection using @Autowired annotation. But, if you are using XML based spring configuration, then you can inject beans via constructor using its constructor-arg element as shown below

<bean id="user" class="com.codippa.User">
    <constructor-arg ref="role"/>
</bean>

<bean id="role" class="com.codippa.Role">
</bean>

If there are multiple constructor arguments, then you can use index  or type attribute to specify order of injection. Example,

<bean id="toyota" class="com.codippa.User">
    <constructor-arg index="0" ref="role"/>
    <constructor-arg index="1" ref="detail"/>
</bean>

<bean id="engine" class="com.codippa.Role">
</bean>

<bean id="detail" class="com.codippa.UserDetail">
</bean>

Advantages of constructor based dependency injection
Constructor-based dependency injection has a number of advantages over setter-based dependency injection.

1. It ensures that all required dependencies are injected, before the bean is used. This is because the dependencies are injected through the constructor and the constructor will not be called unless all dependencies are satisfied.
2. It allows for finer-grained control over the timing of dependency injection, since dependencies are injected only when the class is instantiated.
3. It allows dependencies to be final, which can lead to more robust code.
4. Constructor dependency injection pattern makes it easy to see which dependencies a bean has. This is because the dependencies are listed in the constructor arguments.
5. Constructor dependency injection makes it easy to change the dependencies of a bean.
This is because the dependencies are injected through the constructor, so they can be changed simply by changing the constructor arguments.
Disadvantages of constructor based dependency injection
Following are some disadvantages to using constructor based dependency injection in Spring.
1. It can lead to more verbose code, as each constructor argument needs to be specified.
2. It can make unit testing more difficult, as dependencies need to be mocked or stubbed.
3. This pattern can lead to tightly coupled code.
This is because the dependencies are injected through the constructor, so the classes are tightly coupled to each other.
4. It can make classes more resistant to change, since their constructor signature will not need to be changed if their dependencies change.

Hope the article was useful.