Article start
Java Backend Interview Prep
1. Java Frameworks & Testing

2. Spring Core: IoC, DI, Beans, and Scopes

Understand the Spring container, dependency injection, bean lifecycle, and scopes.

May 29, 2026·23

IoC and Dependency Injection

Inversion of Control means the framework creates and wires objects instead of your code manually calling new everywhere. Dependency Injection is the main technique Spring uses to provide dependencies to a class.

Bean Lifecycle

A Spring bean is created, dependencies are injected, initialization callbacks run, the bean is used, and destroy callbacks run when the context closes.

Common lifecycle hooks:

HookPurpose
ConstructorCreate valid required state
@PostConstructRun setup after dependency injection
initMethodXML/Java config initialization hook
@PreDestroyCleanup before destruction
destroyMethodConfigured cleanup hook

Bean Scopes

Singleton is the default: one bean per Spring container. Prototype creates a new instance each request from the container. Web scopes include request and session.

Interview Framing

Constructor injection is usually preferred for required dependencies because it supports immutability, easier testing, and fail-fast object creation.

Spring Code Examples

Constructor Injection

@Service
public class OrderService {
    private final PaymentClient paymentClient;
    private final OrderRepository orderRepository;

    public OrderService(PaymentClient paymentClient,
                        OrderRepository orderRepository) {
        this.paymentClient = paymentClient;
        this.orderRepository = orderRepository;
    }

    public void placeOrder(Order order) {
        paymentClient.charge(order.total());
        orderRepository.save(order);
    }
}

Bean Lifecycle Hooks

@Component
public class CacheWarmup {
    @PostConstruct
    public void init() {
        System.out.println("Load cache after dependencies are injected");
    }

    @PreDestroy
    public void shutdown() {
        System.out.println("Flush metrics before bean is destroyed");
    }
}

Interview Scenario Practice

Scenario 1: Required Dependencies

Scenario: A service cannot work without its repository and payment client.

Strong answer: Prefer constructor injection. Required dependencies become visible in the constructor, can be marked final, and fail fast if missing.

Why it works: Constructor injection improves testability and makes the class contract obvious.

Common mistake: Using field injection everywhere because it looks shorter. It hides required dependencies and makes unit tests clumsier.

Scenario 2: Cache Warmup

Scenario: You need to load reference data after Spring has injected all dependencies.

Strong answer: Use @PostConstruct for initialization that needs injected collaborators, or a dedicated startup runner for larger boot workflows.

Why it works: The bean is already constructed and dependencies are available.

Common mistake: Doing heavy dependency-based work inside the constructor before Spring has fully wired the object.

Scenario 3: User Data in Singleton Bean

Scenario: A singleton-scoped service stores per-request user information in a field.

Strong answer: Avoid mutable request-specific state in singleton beans. Keep state local to methods, use request scope where appropriate, or pass context explicitly.

Why it works: Singleton beans are shared, so mutable fields can leak values between requests and threads.

Common mistake: Assuming a Spring singleton means one instance per user. It means one instance per Spring container.

Discussion

0 comments

Sign in to share a question or add to the discussion.
Start the discussion

Ask a question or share what stood out to you.