Spring Framework Series — Dependency Injection

devcat
3 min readOct 9, 2023

--

In this blog post, We will understand what is dependency injection and how it is used by spring to create IOC container. In the previous post, we have seen how Spring IOC Container is created from configuration metadata such as from XML, annotation or Java configuration. In this article we are going to look at the concept that is used to construct an object and it’s dependencies.

Dependency Injection

Dependency Injection is a process where objects define their dependencies only through constructor arguments, static factory method or properties that are set on the object instance after it's constructed and returned from a
factory method.

Above definition is taken from spring documentation. Now, Let’s look at what is dependency injection. As the name implies, All the dependencies of the object will be injected while constructing an object or after an object is constructed. There are two ways that dependencies of the object can be created.

  • While creating an object, object itself can construct and initialise all the dependent objects.
  • All the dependent objects are created separately and injected into the bean in the form of properties, constructor arguments, setter methods and static factory method.

Dependency injection is all about removing the control from an object to create it’s dependencies. Since we are taking away the control of dependent object creation from an object. Here, Object does not know anything about it’s dependencies or it’s location. Instead, we create dependencies of object and pass them through constructor arguments or as setter arguments. This is why it is called as Inversion of Control.

Why do we need to use DI?

Dependency Injection makes our program easier to test. With DI decoupling of the objects become more effective. Your class would not know anything about all the dependent objects, or it’s location. It would be easier for us to create stub or mock implementation, When the dependencies of the classes are interfaces or abstract classes.

We have already seen that there are two primary ways that dependencies are injected into a bean.

  • Constructor based
  • Setter based

Constructor Based Injection

When we create a new bean or object, All of its dependencies are created separately and injected into the object via constructor arguments.

The following example shows how to create a bean or object with constructor based DI.

We have UserService class which has UserProfileService as dependent object and it is injected as constructor arguments.

// constructor based DI
class UserService {

private UserProfileService userProfileService;

@Autowired
public UserService(UserProfileService userProfileService) {
this.userProfileService = userProfileService;
}

public UserProfileService getUserProfileService() {
return this.userProfileService;
}

...
...
}

Setter Based Injection

When we create a new bean or object, All of its dependencies are created separately and injected into the object via setter method as arguments. In this approach, when an object is created, it’s dependencies are not initialised or set as null. By using setter methods of an object, we can inject the dependencies after the bean is constructed.

The following example demonstrates how to create a bean or object with setter based DI.

We have UserService class which has UserPermission as dependent object and it is injected as setter arguments.

// setter based DI
class UserService {
...
private UserPermission userPermission;

// property based DI
@Autowired
private UserAddress userAddress;

public UserService() {

}

@Autowired
public void setUserPermission(UserPermission userPermission) {
this.userPermission = userPermission;
}

public UserPermission getUserPermission() {
return this.userPermission;
}
...
...
}

Constructor vs Setter

Which one to choose constructor or setter based injection?.

Constructor based injection is preferable when we create a bean with mandatory dependencies, Setter based injection is suitable for cases where the dependencies of the object are optional.

you can mix both constructor and setter based injection wherever possible. It’s still possible to mandate the dependent objects by adding @Autowired on setter methods.

Conclusion

In this article, we have learned what is dependency injection. It’s a mechanism to create an object and it’s dependencies. We have also seen how Spring IOC Container uses DI to create and inject dependent objects.

--

--