Understanding the Spring Framework's Inversion of Control Container

Spring is a lightweight framework that provides a container for managing Inversion of Control (IoC) and Aspect-Oriented Programming (AOP).

Inversion of Control (IoC)

IoC is a design principle where the control over object creation and dependency management is transferred from the application code to an external container. There are two primary methods for achieving this:

  • Dependency Lookup (DL): The application code requests dependencies from the container.
  • Dependency Injection (DI): The container automatically supplies dependencies to the application components.

Spring implements IoC primarily through Dependency Injection.

Understanding Dependencies

A dependency exists when one class requires the functionality of another class to perform its operations.

Programming to Interfaces: A Recap

When a method can have multiple implementations, programming to an interface is a common practice. This example simulates a user login system, omitting actual database connectivity.

1. Data Access Layer (DAO)

Interface AuthenticationDao:

package com.example.auth.dao;

public interface AuthenticationDao {
    boolean authenticate(String username, String password);
}

Concrete implementations:

package com.example.auth.dao.impl;

import com.example.auth.dao.AuthenticationDao;

public class JdbcAuthDao implements AuthenticationDao {
    public boolean authenticate(String username, String password) {
        System.out.println("Authenticating via JDBC implementation.");
        return true;
    }
}
package com.example.auth.dao.impl;

import com.example.auth.dao.AuthenticationDao;

public class CustomAuthDao implements AuthenticationDao {
    public boolean authenticate(String username, String password) {
        System.out.println("Authenticating via custom implementation.");
        return true;
    }
}

2. Service Layer

package com.example.auth.service;

import com.example.auth.dao.AuthenticationDao;

public class AuthService {
    private AuthenticationDao authDao;

    // Constructor-based injection
    public AuthService(AuthenticationDao authDao) {
        this.authDao = authDao;
    }

    // Setter-based injection
    public void setAuthDao(AuthenticationDao authDao) {
        this.authDao = authDao;
    }

    public boolean login(String username, String password) {
        return authDao.authenticate(username, password);
    }
}

3. Test Class (Without Spring)

package com.example.auth.test;

import org.junit.Test;
import com.example.auth.dao.impl.JdbcAuthDao;
import com.example.auth.service.AuthService;

public class LoginTest {
    @Test
    public void testLoginWithoutContainer() {
        // Using constructor
        // AuthService service = new AuthService(new CustomAuthDao());

        // Using setter
        AuthService service = new AuthService();
        service.setAuthDao(new JdbcAuthDao());

        service.login("user", "pass");
    }
}

In compiled languages like Java, changing implementation details requires code modification and recompilation. Using configuration files for dependency management avoids this.

Dependency Injection

Dependency Injection is the process where an object receives its dependencies from an external source (the container) rather than creating them internally. This is a key mechanism for achieving looce coupling, as dependencies are defined externally, not hardcoded.

Spring's IoC Container

Spring's IoC container manages component dependencies through DI, facilitating loose coupling. Common versions in use are 3.2 and 4.2.

1. Required Libraries For a basic Java project, include the core Spring libraries, JUnit (e.g., junit-4.12.jar and hamcrest-core-1.3.jar), and a logging framework like Log4j (log4j-1.2.17.jar).

2. Configuration File applicationContext.xml The container configuration is defined in an XML file. The underlying mechanism for IoC is reflection.

Example Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- Bean definitions -->
    <bean id="jdbcAuthDao" class="com.example.auth.dao.impl.JdbcAuthDao"/>
    <bean id="customAuthDao" class="com.example.auth.dao.impl.CustomAuthDao"/>

    <bean id="authService" class="com.example.auth.service.AuthService">
        <!-- Constructor Injection -->
        <constructor-arg ref="customAuthDao"/>
        <!-- Setter Injection (property name matches setter method) -->
        <!-- <property name="authDao" ref="jdbcAuthDao"/> -->
    </bean>

</beans>

3. Updated Test Class (Using Spring Container)

package com.example.auth.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.example.auth.service.AuthService;

public class LoginTest {
    @Test
    public void testLoginWithSpring() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        AuthService service = (AuthService) context.getBean("authService");
        service.login("user", "pass");
    }
}

Tags: Spring Framework Inversion of Control Dependency Injection java configuration

Posted on Fri, 26 Jun 2026 16:35:00 +0000 by rhysmeister