Spring – Inversion of Control vs Dependency Injection

In software engineering, inversion of control (IoC) is a programming technique in which object coupling is bound at run time by an assembler object and is typically not known at compile time using static analysis. In this spring tutorial, learn the difference between ioc and dependency injection in spring with example.

Table of Contents

1. Inversion of Control (IoC)
2. Dependency Injection (DI)
3. How to Implement Inversion of Control
4. IoC in Spring Framework
5. Ways to create beans in Spring
6. Dependency Injection in Spring Framework
7. IoC vs DI Interview Questions

1. What is Inversion of Control (IoC)

In traditional programming, the flow of the business logic is determined by objects that are statically assigned to one another. With inversion of control, the flow depends on the object graph that is instantiated by the assembler and is made possible by object interactions being defined through abstractions. The binding process is achieved through dependency injection, although some argue that the use of a service locator also provides inversion of control.

Inversion of control as a design guideline serves the following purposes:

  1. There is a decoupling of the execution of a certain task from implementation.
  2. Every module can focus on what it is designed for.
  3. Modules make no assumptions about what other systems do but rely on their contracts.
  4. Replacing modules has no side effect on other modules.

2. What is Dependency Injection (DI)

IoC is a design paradigm with the goal of giving more control to the targeted components of your application, the ones getting the work done. While Dependency injection is a pattern used to create instances of objects that other objects rely on without knowing at compile time which class will be used to provide that functionality. IoC relies on dependency injection because a mechanism is needed in order to activate the components providing the specific functionality.

The two concepts work together in this way to allow for much more flexible, reusable, and encapsulated code to be written. As such, they are important concepts in designing object-oriented solutions.

3. How to implement IoC

In object-oriented programming, there are several basic techniques to implement inversion of control. These are:

  1. using a factory pattern
  2. using a service locator pattern
  3. using a dependency injection of any given below type:
    • a constructor injection
    • a setter injection
    • an interface injection

4. Inversion of control in Spring

The org.springframework.beans and org.springframework.context packages provide the basis for the Spring Framework’s IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing objects of any nature. The ApplicationContext interface builds on top of the BeanFactory (it is a sub-interface) and adds other functionality such as easier integration with Spring’s AOP features, message resource handling (for use in internationalization), event propagation, and application-layer specific contexts such as the WebApplicationContext for use in web applications.

The BeanFactory is the actual representation of the Spring IoC container that is responsible for containing and otherwise managing the aforementioned beans. The BeanFactory interface is the central IoC container interface in Spring.

container-magic-1508070

There are a number of implementations of the BeanFactory interface. The most commonly used BeanFactory implementation is the XmlBeanFactory class. Other commonly used class is XmlWebApplicationContext. Depending on the bean definition, the factory will return either an independent instance of a contained object (the Prototype design pattern), or a single shared instance (a superior alternative to the Singleton design pattern, in which the instance is a singleton in the scope of the factory). Which type of instance will be returned depends on the bean factory configuration: the API is the same.

Before we dive into dependency injection types, let first identify the ways of creating a bean in spring framework as it will help in understanding the things in next section.

5. How to create beans in Spring

A bean definition can be seen as a recipe for creating one or more actual objects. The container looks at the recipe for a named bean when asked, and uses the configuration metadata encapsulated by that bean definition to create (or acquire) an actual object.

5.1. Using constructor

When creating a bean using the constructor approach, all normal classes are usable by and compatible with Spring. That is, the class being created does not need to implement any specific interfaces or be coded in a specific fashion. Just specifying the bean class should be enough. When using XML-based configuration metadata you can specify your bean class like so:

<bean id="exampleBean"/>

5.2. Using static factory method

When defining a bean which is to be created using a static factory method, along with the class attribute which specifies the class containing the static factory method, another attribute named factory-method is needed to specify the name of the factory method itself.

<bean id="exampleBean" factory-method="createInstance"/>

Spring expects to be able to call this method and get back a live object, which from that point on is treated as if it had been created normally via a constructor.

5.3. Using instance factory method

In a fashion similar to instantiation via a static factory method, instantiation using an instance factory method is where the factory method of an existing bean from the container is invoked to create the new bean.

<bean id="myFactoryBean"  class="...">

<bean id="exampleBean"  factory-bean="myFactoryBean" factory-method="createInstance"></bean>

6. Dependency Injection in Spring

The basic principle behind Dependency Injection (DI) is that objects define their dependencies only through constructor arguments, arguments to a factory method, or properties which are set on the object instance after it has been constructed or returned from a factory method. Then, it is the job of the container to actually inject those dependencies when it creates the bean. This is fundamentally the inverse, hence the name Inversion of Control (IoC).

6.1. Setter Injection

Setter-based DI is realized by calling setter methods on your beans after invoking a no-argument constructor or no-argument static factory method to instantiate your bean.

public class TestSetterDI {

DemoBean demoBean = null;

public void setDemoBean(DemoBean demoBean) {
	this.demoBean = demoBean;
}
}

6.2. Constructor Injection

Constructor-based DI is realized by invoking a constructor with a number of arguments, each representing a collaborator. Additionally, calling a static factory method with specific arguments to construct the bean, can be considered almost equivalent, and the rest of this text will consider arguments to a constructor and arguments to a static factory method similarly.

public class ConstructorDI {

DemoBean demoBean = null;

public TestSetterDI (DemoBean demoBean) {
	this.demoBean = demoBean;
}
}

6.3. Interface Injection

In this methodology we implement an interface from the IOC framework. IOC framework will use the interface method to inject the object in the main class. It is much more appropriate to use this approach when you need to have some logic that is not applicable to place in a property. Such as logging support.

public void SetLogger(ILogger logger)
{
  _notificationService.SetLogger(logger);
  _productService.SetLogger(logger);
}

7. Interview Questions

7.1. What is difference between component and service?

A component is a glob of software that’s intended to be used, without change, by an application that is out of the control of the writers of the component. By ‘without change’ means that the using application doesn’t change the source code of the components, although they may alter the component’s behavior by extending it in ways allowed by the component writers.

A service is similar to a component in that it’s used by foreign applications. The main difference is that a component to be used locally (think jar file, assembly, dll, or a source import). A service will be used remotely through some remote interface, either synchronous or asynchronous (eg web service, messaging system, RPC, or socket.)

7.2. How DI is different from Service locator pattern?

The key benefit of a Dependency Injector is that it allows to plug-in a suitable implementation of a service according to environment and usage. Injection isn’t the only way to break this dependency, another is to use a service locator. The basic idea behind a service locator is to have an object that knows how to get hold of all of the services that an application might need. It then scans all such services and store them as a singleton Registry. When asked for a service implementation, a requester can query the registry with a token and get appropriate implementation.

Mostly these registries are populated via some configuration files. The key difference is that with a Service Locator every user of a service has a dependency to the locator. The locator can hide dependencies to other implementations, but you do need to see the locator.

7.3. Which one should be better to use i.e. service locator or dependency injection?

Well, it as I already said that key difference is that with a Service Locator every user of a service has a dependency to the locator. It means you must know the details of service locator in terms of input and output. So, it actually becomes the deciding factor which pattern to choose from.

If it is easy and necessary to maintain registry information then go for service locator, or else simply use dependency injection as it does not bother the users of service with any per-requisites.

7.4. Which is better constructor injection or setter injection?

The choice between setter and constructor injection is interesting as it mirrors a more general issue with object-oriented programming – should you fill fields in a constructor or with setters.
Constructors with parameters give you a clear statement of what it means to create a valid object in an obvious place. If there’s more than one way to do it, create multiple constructors that show the different combinations. Another advantage with constructor initialization is that it allows you to clearly hide any fields that are immutable by simply not providing a setter. I think this is important – if something shouldn’t change then the lack of a setter communicates this very well. If you use setters for initialization, then this can become a pain.

But If you have a lot of constructor parameters things can look messy, particularly in languages without keyword parameters. If you have multiple ways to construct a valid object, it can be hard to show this through constructors, since constructors can only vary on the number and type of parameters. Constructors also suffer if you have simple parameters such as strings. With setter injection you can give each setter a name to indicate what the string is supposed to do. With constructors you are just relying on the position, which is harder to follow.

My preference is to start with constructor injection, but be ready to switch to setter injection as soon as the problems I’ve outlined above start to become a problem.

7.5. What is Bean Factory ?

A BeanFactory is like a factory class that contains a collection of beans. The BeanFactory holds Bean Definitions of multiple beans within itself and then instantiates the bean whenever asked for by clients.

BeanFactory is able to create associations between collaborating objects as they are instantiated. This removes the burden of configuration from bean itself and the beans client. BeanFactory also takes part in the life cycle of a bean, making calls to custom initialization and destruction methods.

7.6. What is Application Context?

A bean factory is fine to simple applications, but to take advantage of the full power of the Spring framework, you may want to move up to Springs more advanced container, the application context. On the surface, an application context is same as a bean factory.Both load bean definitions, wire beans together, and dispense beans upon request. But it also provides:

  • A means for resolving text messages, including support for internationalization.
  • A generic way to load file resources.
  • Events to beans that are registered as listeners.

7.7. What are the common implementations of the Application Context?

The three commonly used implementation of ApplicationContext are:

  1. ClassPathXmlApplicationContext : It Loads context definition from an XML file located in the classpath, treating context definitions as classpath resources. The application context is loaded from the application’s classpath by using the code .
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
  2. FileSystemXmlApplicationContext : It loads context definition from an XML file in the filesystem. The application context is loaded from the file system by using the code .
    ApplicationContext context = new FileSystemXmlApplicationContext("bean.xml");
  3. XmlWebApplicationContext : It loads context definition from an XML file contained within a web application.

7.8. What should be used preferably BeanFactory or ApplicationContext?

A BeanFactory pretty much just instantiates and configures beans. An ApplicationContext also does that, and it provides the supporting infrastructure to enable lots of enterprise-specific features such as transactions and AOP.

In short, favor the use of an ApplicationContext.

In this tutorial, we learned the difference between ioc and di in spring.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

16 thoughts on “Spring – Inversion of Control vs Dependency Injection”

  1. Hi pankaj,

    I think the question you asked should be — is ioc possible WITHOUT di ?

    It may be a typo.

    And thanks for the discussion on this. It helped to clearly understand ioc and di

    Reply
  2. Hi Lokesh,
    your blog really gives me a good insight of the technology.
    Thanks for taking time and pain in collecting this information and making it available for the java geeks.

    Great work and keep going.
    All The Best

    Reply
  3. Hi lokesh,

    I got this interview question in one of the interviews.

    Is IOC possible with DI?

    I answered Yes.

    DI is Injecting Dependancies.
    Since the process of DI is managed by the container and not us , the flow is reversed hence it is Inversion Of Control.

    So ideally, The Servlet which instantiated by container, whose lifecyle methods are managed by the web container, is also IOC? but not DI?

    Am I correct? Please explain.

    Regards,
    -Pankaj.

    Reply
    • You are right for most of the part. I have only different opinion on example given i.e. Servlets.

      IOC basically facilitates having different components designed and coded separately and later used together by defining their relation with DI. In case of servlets we do not have multiple components. There is only one component i.e. servlet and you can not change the way how a servlet works. A servlet is basically combination of front controller and mediator pattern, which container uses internally.

      https://en.wikipedia.org/wiki/Front_Controller_pattern
      https://en.wikipedia.org/wiki/Mediator_pattern

      Actually, it is a very good topic and I would like others to jump into discussion with their thoughts.

      Reply
      • In my Opinion , DI and IOC are two different things. DI is a Injecting dependanices.

        Suppose if I have a Segment Object which depends on two Point objects, Two point objects will be created and instantiated seperately, and can be injected to segment object.

        This is injecting DEPENDANCIES (Two Point objects) into the dependant object(Segment object) ,which we as the application programmers would have done manually which is DI but not IOC (i.e. Flow is straight.(Application to framework))

        But in Spring, since it is a framework or Container who does that job of injecting dependancies (DI) and not us, The flow of control is reversed, (Framework to Application) it is DI with IOC.
        It is IOC not because of DI, but because flow of control is reversed.

        However, When we talk about servlet. It is the servlet container that loads and instantiates servlets, but since it is independant servlet and has no depandancies to be injected, there is no DI, but since it is not us and it is the servlet container which instanciates and loads the servlets, the flow is reversed(i.e. Framework to Application) and hence it is IOC (IOC without DI)

        I Hope I am correct and explanation is understandable. Please correct me if I am wrong anywhere.

        Regards,
        -Pankaj

        Reply
        • Thanks for detailed comment. I appreciate it. In a sense you are right. IOC also helps in creating executable components without much details of background infrastructure. A valid point can be make in your case when servlet container provides advanced capabilities to servlet e.g. thread management, session handling and much more. So, servlets can be argued as IOC as well. I agree on this with you.
          In fact IOC is much broader term and can include anywhere control of execution is put at separate place, away from executables.
          With or without DI?? I really doubt myself. Basically we provide servlet mappings in web.xml. Should we consider them as DI? My take is YES. What you think?

          Reply
          • Considering Servlets as DI, I think, Container just take lookup of Servlets in web.xml and instantiates the mapped servlet. But I think Container does not Inject any dependancies in the servlets?

            If the container would have injected any Objects to servlets, It would have been DI (DI with IOC)

            Is it that, Servlet object is dependant on other objects and servlets cannot be formed without injecting those dependancies? No right? Servlets are created by the container without injecting anything hence it is IOC without DI.

            If the servlet object would have been dependant on any object, and those objects would have been injected by Container like ( Segment object has to have 2 point objects, i.e Segment object is completely dependant on Point objects, ) then it would have been a DI, (DI with IOC.) which is not the case.?

            Even in Case of advanced capabilities the container does not have to inject any resources to servlet, Servlet is managed by container, but container does not have to inject anything to servlet instance, to form servlet, right? Hence It is not DI. but IOC.

            Summary:

            IOC- Flow of control is from Container to application.

            DI- If One object is dependant on the other and if other object needs to be injected to that object,

            IOC without DI- Flow of control is from Container to application but object is not dependant on the other and hence no need to inject dependancies. Container just instantiates the object without doing any dependancy Injection.

            DI without IOC- If One object is dependant on the other and if other object needs to be injected to that object, If this process is done by the application directly and no container is involved, it is DI without IOC,

            IOC With DI- – If One object is dependant on the other and if other object needs to be injected to that object, If this process is done by the container, The flow of control is reversed, hence it is IOC with DI,

            Hope I am right and this clears the concept. Correct me if I am wrong.

            Regards,
            -Pankaj.

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.