IOC Container


IOC Container Interview with follow-up questions

1. What is the IOC Container in Spring?

The IoC (Inversion of Control) container is the core of Spring: it creates, configures, wires, and manages the lifecycle of beans. "Inversion of control" means you don't new up and connect your objects — the container does, based on configuration metadata, and hands you ready-to-use beans. Dependency Injection is how it supplies each bean's collaborators.

Its two interfaces:

  • BeanFactory — the basic container contract (lazy, minimal).
  • ApplicationContext — the production container (a BeanFactory superset) adding event publishing, i18n, resource loading, and AOP integration. This is what you actually use.
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
var svc = ctx.getBean(OrderService.class);   // created and wired by the container

Points worth making: the container reads metadata from annotations/Java config (@Component, @Bean, component scanning) or legacy XML; resolves dependencies by type; manages scopes and lifecycle callbacks; and is the basis for loose coupling and testability. In Spring Boot, SpringApplication.run() creates this container automatically — it's the same IoC container, just bootstrapped for you.

↑ Back to top

Follow-up 1

Can you explain the difference between BeanFactory and ApplicationContext?

BeanFactory and ApplicationContext are both implementations of the IOC Container in Spring. The main difference between them is that ApplicationContext is a more feature-rich container that extends the functionality of BeanFactory.

BeanFactory provides the basic features of the IOC Container, such as bean instantiation, dependency injection, and lifecycle management. It is a lightweight container suitable for simple applications.

ApplicationContext, on the other hand, adds additional features like internationalization, event publishing, and AOP (Aspect-Oriented Programming) support. It is a more advanced container that is recommended for most Spring applications.

Follow-up 2

What are the different types of IOC Containers in Spring?

Spring provides two main types of IOC Containers:

  1. BeanFactory: It is the simplest and most lightweight IOC Container in Spring. It provides basic IOC functionality, but lacks some of the advanced features provided by ApplicationContext.

  2. ApplicationContext: It is a more feature-rich IOC Container that extends the functionality of BeanFactory. It provides additional features like internationalization, event publishing, and AOP support. ApplicationContext is recommended for most Spring applications.

Follow-up 3

How does the IOC Container work in Spring?

The IOC Container in Spring works by following the principle of dependency injection. Instead of objects creating and managing their dependencies, the IOC Container takes responsibility for creating and wiring the dependencies between objects.

When the Spring application starts, the IOC Container reads the configuration metadata (XML, Java annotations, or Java code) to determine the beans to be created. It then creates the beans and injects the dependencies based on the configuration.

The IOC Container also manages the lifecycle of the beans, ensuring that they are created, initialized, and destroyed properly.

Follow-up 4

What is the role of the IOC Container in Spring?

The role of the IOC Container in Spring is to manage the creation, configuration, and lifecycle of objects (beans) in a Spring application. It promotes loose coupling between objects by using dependency injection to wire the dependencies between beans.

The IOC Container also provides additional features like bean scope management, AOP support, and event publishing. It simplifies the development of Spring applications by handling the complex tasks of object creation and dependency management.

2. What is Dependency Injection in Spring?

Dependency Injection is the technique by which Spring's IoC container supplies a bean's dependencies from the outside instead of the bean creating them itself. It's the concrete mechanism behind Inversion of Control, and it delivers loose coupling, testability (inject mocks), and clear, declarative wiring.

The three styles, with the recommended one called out:

  • Constructor injectionpreferred: dependencies are final and mandatory, the object is always valid, and it's trivial to test without Spring. With one constructor, @Autowired is optional.
  • Setter injection — for optional dependencies.
  • Field injection — concise but discouraged (hidden dependencies, not final, hard to test).
@Service
class ReportService {
  private final UserRepository users;
  ReportService(UserRepository users) { this.users = users; }   // constructor DI
}

The details interviewers reward: Spring autowires by type, using @Qualifier to disambiguate multiple candidates and @Primary to mark a default; @Autowired triggers the injection; and constructor injection is the modern best practice. This is the single most important concept in Spring — it's why the IoC container exists.

↑ Back to top

Follow-up 1

What are the different types of Dependency Injection in Spring?

There are three types of Dependency Injection in Spring:

  1. Constructor Injection: In this type, the dependencies are provided through the class constructor.

  2. Setter Injection: In this type, the dependencies are provided through setter methods.

  3. Field Injection: In this type, the dependencies are directly injected into the class fields using annotations.

Follow-up 2

How does Dependency Injection work in Spring?

Dependency Injection in Spring works by using the concept of Inversion of Control (IoC) container. The IoC container is responsible for managing the lifecycle of objects and injecting their dependencies. When a class needs a dependency, it declares a dependency on an interface or a class. The IoC container then resolves the dependency and injects it into the class. This allows the class to focus on its core functionality without worrying about creating or managing its dependencies.

Follow-up 3

What are the benefits of using Dependency Injection in Spring?

Some of the benefits of using Dependency Injection in Spring are:

  1. Loose coupling: Dependency Injection helps in achieving loose coupling between classes, making the code more modular and flexible.

  2. Testability: With Dependency Injection, it becomes easier to write unit tests for classes, as the dependencies can be easily mocked or replaced.

  3. Reusability: By injecting dependencies, the classes become more reusable, as they can be used in different contexts with different implementations of the dependencies.

  4. Maintainability: Dependency Injection makes the code more maintainable, as changes to the dependencies can be easily made without modifying the class that uses them.

  5. Scalability: Dependency Injection allows for easy scalability of the application, as new dependencies can be added or existing ones can be replaced without modifying the existing code.

Follow-up 4

Can you give an example of Dependency Injection in Spring?

Sure! Here's an example of Dependency Injection in Spring using Constructor Injection:

public class UserService {

    private UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // Rest of the class
}

public class UserRepository {
    // Implementation of UserRepository
}

@Configuration
public class AppConfig {

    @Bean
    public UserService userService(UserRepository userRepository) {
        return new UserService(userRepository);
    }

    @Bean
    public UserRepository userRepository() {
        return new UserRepository();
    }

    // Other bean definitions
}

3. What is BeanFactory in Spring?

BeanFactory is the most basic interface of Spring's IoC container — it defines the fundamental contract for accessing and managing beans: instantiating them, wiring dependencies, and resolving them by name or type. It's lazy by nature (beans are created on demand).

In practice you rarely use BeanFactory directly; you use its richer subinterface ApplicationContext, which adds the features real apps need:

BeanFactory ApplicationContext
Bean instantiation lazy (on request) eager for singletons (at startup)
Extras none events, i18n, resource loading, AOP, annotation config
Typical use rare / memory-constrained standard
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

The point interviewers look for: BeanFactory is the foundational abstraction, but ApplicationContext is what you use because it eagerly initializes singletons (surfacing wiring errors at startup, not first use) and provides the enterprise features. Both are the container; ApplicationContext is the production-grade one — and in Spring Boot it's created for you.

↑ Back to top

Follow-up 1

What is the role of BeanFactory in Spring?

The role of BeanFactory in Spring is to provide a central registry for managing and configuring beans. It acts as a container for holding bean definitions and creating bean instances when requested. BeanFactory is responsible for managing the lifecycle of beans, including their creation, initialization, and destruction. It also supports dependency injection, allowing beans to be wired together and dependencies to be resolved.

Follow-up 2

How does BeanFactory work in Spring?

BeanFactory works by loading bean definitions from various sources, such as XML configuration files or Java annotations. It then creates bean instances based on these definitions and manages their lifecycle. When a bean is requested, BeanFactory checks if it has already been created. If not, it creates a new instance and applies any necessary initialization. BeanFactory also handles dependency injection by resolving and injecting dependencies into beans as needed.

Follow-up 3

What is the difference between BeanFactory and ApplicationContext in Spring?

BeanFactory and ApplicationContext are both interfaces in the Spring framework, but they have some differences. BeanFactory is the basic container interface, providing the core functionality for managing beans. ApplicationContext is a sub-interface of BeanFactory and adds additional features, such as internationalization support, event publishing, and application context hierarchy. ApplicationContext is generally preferred over BeanFactory for most applications, as it provides a more feature-rich and convenient way to work with Spring.

Follow-up 4

Can you give an example of how to use BeanFactory in Spring?

Sure! Here's an example of how to use BeanFactory in Spring:

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class Main {
    public static void main(String[] args) {
        // Load the bean definitions from an XML file
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));

        // Get a bean instance by name
        MyBean myBean = (MyBean) beanFactory.getBean("myBean");

        // Use the bean
        myBean.doSomething();
    }
}

In this example, we create a BeanFactory by loading bean definitions from an XML file called "beans.xml". We then retrieve a bean instance by its name ("myBean") and use it to perform some operation.

4. What is ApplicationContext in Spring?

ApplicationContext is the central, production-grade interface of Spring's IoC container. It's a superset of BeanFactory that manages the full bean lifecycle and adds the enterprise features applications actually rely on:

  • Dependency injection and bean management (eagerly instantiating singletons at startup).
  • Event publishing/listening (ApplicationEventPublisher, @EventListener).
  • Internationalization (MessageSource).
  • Resource loading (classpath/file/URL).
  • AOP and annotation-based configuration integration, plus environment/profile support.
var ctx = new AnnotationConfigApplicationContext(AppConfig.class);
OrderService svc = ctx.getBean(OrderService.class);
ctx.publishEvent(new OrderPlaced(id));

Common implementations: AnnotationConfigApplicationContext (Java config) and the web variants. The contrast interviewers want: vs BeanFactory, ApplicationContext eagerly initializes singletons (catching misconfiguration at startup) and provides events/i18n/AOP — which is why it's the one you use. In Spring Boot, SpringApplication.run() returns a ConfigurableApplicationContext, so it's created and managed for you.

↑ Back to top

Follow-up 1

What is the role of ApplicationContext in Spring?

The role of ApplicationContext in Spring is to provide a container for managing and accessing beans in a Spring application. It is responsible for creating and configuring beans, resolving dependencies, and managing the lifecycle of beans. ApplicationContext also provides additional features such as event publishing, AOP, and internationalization.

Follow-up 2

How does ApplicationContext work in Spring?

ApplicationContext works in Spring by creating and managing beans in a Spring application. When an ApplicationContext is created, it reads the configuration metadata (XML, Java annotations, or Java code) that defines the beans and their dependencies. It then instantiates the beans, resolves their dependencies, and manages their lifecycle. ApplicationContext also provides additional features such as event publishing, AOP, and internationalization.

Follow-up 3

What is the difference between ApplicationContext and BeanFactory in Spring?

The main difference between ApplicationContext and BeanFactory in Spring is that ApplicationContext is a sub-interface of BeanFactory and provides additional features. ApplicationContext extends the functionality of BeanFactory by adding support for internationalization, event publishing, AOP, and more. ApplicationContext is recommended for most applications as it provides a richer set of features compared to BeanFactory.

Follow-up 4

Can you give an example of how to use ApplicationContext in Spring?

Sure! Here's an example of how to use ApplicationContext in Spring:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyApp {
    public static void main(String[] args) {
        // Create an ApplicationContext
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        // Get a bean from the ApplicationContext
        MyBean myBean = context.getBean(MyBean.class);

        // Use the bean
        myBean.doSomething();
    }
}

In this example, we create an ApplicationContext using the ClassPathXmlApplicationContext implementation and specify the XML configuration file applicationContext.xml. We then retrieve a bean of type MyBean from the ApplicationContext and use it.

5. How does the IOC Container manage the lifecycle of a Bean?

The container drives each bean through a well-defined lifecycle:

  1. Instantiation — the container reads the bean definition and creates the instance.
  2. Populate properties / dependency injection — collaborators are injected (constructor/setter/field).
  3. Aware callbacks — if implemented, BeanNameAware, ApplicationContextAware, etc.
  4. BeanPostProcessor before-init — e.g. where AOP proxies and annotations are applied.
  5. Initialization@PostConstruct, then InitializingBean.afterPropertiesSet(), then a custom initMethod.
  6. BeanPostProcessor after-init — proxy wrapping finalized.
  7. Bean is ready / in use.
  8. Destruction (on context shutdown, for singletons) — @PreDestroy, then DisposableBean.destroy(), then a custom destroyMethod.
@Component
class Cache {
  @PostConstruct void warmUp() { /* load */ }
  @PreDestroy   void flush()  { /* cleanup */ }
}

Points interviewers reward: prefer the @PostConstruct/@PreDestroy annotations (cleanest, framework-agnostic) over the Spring-specific interfaces; destruction callbacks fire only for singletons (the container doesn't manage the full lifecycle of prototype beans); and BeanPostProcessor is the extension point Spring itself uses to apply AOP, transactions, and annotation processing. This lifecycle is exactly where initialization (DB warmup, validation) and cleanup (closing resources) belong.

↑ Back to top

Follow-up 1

What are the different stages in the lifecycle of a Bean?

The different stages in the lifecycle of a Bean are:

  1. Instantiation: The Bean is created by the IOC Container.
  2. Population of properties: The dependencies of the Bean are injected by the IOC Container.
  3. Initialization: Any initialization logic specified by the Bean is executed.
  4. Destruction: When the IOC Container is shut down, the Bean is destroyed by calling its destroy method.

Follow-up 2

How can you customize the lifecycle of a Bean in Spring?

You can customize the lifecycle of a Bean in Spring by implementing the InitializingBean and DisposableBean interfaces or by using the @PostConstruct and @PreDestroy annotations.

  1. Implementing InitializingBean and DisposableBean interfaces:
public class MyBean implements InitializingBean, DisposableBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        // Initialization logic
    }

    @Override
    public void destroy() throws Exception {
        // Destruction logic
    }

}
  1. Using @PostConstruct and @PreDestroy annotations:
public class MyBean {

    @PostConstruct
    public void init() {
        // Initialization logic
    }

    @PreDestroy
    public void destroy() {
        // Destruction logic
    }

}

Follow-up 3

What is the role of the IOC Container in managing the lifecycle of a Bean?

The role of the IOC Container in managing the lifecycle of a Bean is to create, initialize, and destroy the Bean as per its configuration. The IOC Container reads the Bean definitions from the configuration metadata, creates the Bean instances, injects the dependencies, and performs any necessary initialization. When the IOC Container is shut down, it destroys the Bean instances by calling their destroy methods.

Follow-up 4

Can you give an example of how the IOC Container manages the lifecycle of a Bean in Spring?

Sure! Here's an example of how the IOC Container manages the lifecycle of a Bean in Spring:

public class MyBean {

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void init() {
        System.out.println("Initializing MyBean");
    }

    public void destroy() {
        System.out.println("Destroying MyBean");
    }

}

In the above example, the IOC Container creates an instance of MyBean, injects the name property, and calls the init method during initialization. When the IOC Container is shut down, it calls the destroy method to destroy the MyBean instance.

6. What is a circular dependency in Spring and how do you resolve it?

A circular dependency is when two (or more) beans depend on each other — A needs B and B needs A — so the container can't decide which to create first. With constructor injection on both sides, Spring fails at startup with a BeanCurrentlyInCreationException (this became the default behavior in Spring Boot 2.6+, which disabled circular references).

How to handle it, best option first:

  • Redesign — a cycle usually signals a design smell; extract the shared logic into a third bean, or merge/realign responsibilities. This is the preferred fix.
  • @Lazy on one injection point — Spring injects a proxy and resolves the real bean on first use, breaking the construction cycle.
  • Setter/field injection on one side — allows the beans to be created first and wired afterward (works, but constructor injection is otherwise preferred).
  • ObjectProvider/@Autowired ObjectFactory — defer resolution until needed.
  • (Last resort) spring.main.allow-circular-references=true to restore the old behavior — masks the problem rather than fixing it.

Interviewers ask this to see whether you reach for a quick toggle or recognize it as a design issue to refactor. The clean answer: treat the cycle as a smell, break it by extracting a collaborator, and use @Lazy only if a redesign isn't feasible.

↑ Back to top

Live mock interview

Mock interview: IOC Container

Intermediate ~5 min Your own free AI key

Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.