Lesson

spring IOC

spring/Spring Boot

Spring IoC (Inversion of Control)

Introduction

In this tutorial, you will learn:

  • What is IoC

  • What is Dependency Injection

  • Types of IoC containers

  • Real example using SIM (Airtel, Jio)

  • XML configuration

  • Java configuration

  • Annotation-based configuration (most important)

What is IoC?

IoC means Spring controls object creation.

Instead of creating objects manually:

  • Spring creates objects

  • Spring injects dependencies

Simple example

Without Spring:

  • You create object using new keyword

With Spring:

  • Spring gives you object

Why IoC?

  • Loose coupling

  • Easy to change implementation

  • Better testing

  • Clean code

Types of IoC Container

1. BeanFactory

  • Basic container

  • Lightweight

2. ApplicationContext

  • Advanced container

  • Used in real projects

Create Project

Step 1: Create Maven Project

  • GroupId: com.anil

  • ArtifactId: spring-ioc-demo

Step 2: Add Dependency

java
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>6.1.3</version>
    </dependency>
</dependencies>

Create Interface

java
public interface Sim {
    void calling();
    void data();
}

// Create Implementations Airtel.java

public class Airtel implements Sim {

    @Override
    public void calling() {
        System.out.println("Airtel Calling");
    }

    @Override
    public void data() {
        System.out.println("Airtel Data");
    }
}

// Create Implementations Jio.java
public class Jio implements Sim {

    @Override
    public void calling() {
        System.out.println("Jio Calling");
    }

    @Override
    public void data() {
        System.out.println("Jio Data");
    }
}

Without Spring IoC

java
public class Mobile {

    public static void main(String[] args) {

        Sim sim = new Jio();

        sim.calling();
        sim.data();
    }
}

Problem

  • Tight coupling

  • Cannot switch easily

Using Spring IoC (XML)

Step 1: beans.xml

plaintext
<?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
       https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="sim" class="com.p1.Jio"/>

</beans>

Step 2: Mobile.java

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

public class Mobile {

    public static void main(String[] args) {

        ApplicationContext context =
                new ClassPathXmlApplicationContext("beans.xml");

        Sim sim = context.getBean("sim", Sim.class);

        sim.calling();
        sim.data();
    }
}

Change Implementation Easily

Change only XML:

plaintext
<bean id="sim" class="com.example.Airtel"/>

No change in Java code

Java-Based Configuration

AppConfig.java

java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public Sim sim() {
        return new Jio(); // change to Airtel
    }
}

Mobile.java

java
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Mobile {

    public static void main(String[] args) {

        ApplicationContext context =
                new AnnotationConfigApplicationContext(AppConfig.class);

        Sim sim = context.getBean(Sim.class);

        sim.calling();
        sim.data();
    }
}

Annotation-Based Configuration

Step 1: Config Class

plaintext
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.example")
public class AppConfig {
}

Step 2: Add @Component

plaintext
import org.springframework.stereotype.Component;

@Component
public class Airtel implements Sim {

    public void calling() {
        System.out.println("Airtel Calling");
    }

    public void data() {
        System.out.println("Airtel Data");
    }
}
plaintext
@Component
public class Jio implements Sim {

    public void calling() {
        System.out.println("Jio Calling");
    }

    public void data() {
        System.out.println("Jio Data");
    }
}

Step 3: Use @Autowired

plaintext
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Mobile {

    @Autowired
    private Sim sim;

    public void useSim() {
        sim.calling();
        sim.data();
    }
}

Step 4: Main Class

plaintext
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

    public static void main(String[] args) {

        ApplicationContext context =
                new AnnotationConfigApplicationContext(AppConfig.class);

        Mobile mobile = context.getBean(Mobile.class);

        mobile.useSim();
    }
}

Problem: Multiple Beans Error

Error: NoUniqueBeanDefinitionException

Reason:

  • Two beans (Airtel, Jio)

Solutions

1. @Primary

plaintext
@Component
@Primary
public class Airtel implements Sim {
}

2. @Qualifier

plaintext
@Autowired
@Qualifier("jio")
private Sim sim;

3. Custom Bean Name

plaintext
@Component("jioBean")
public class Jio implements Sim {
}
plaintext
@Autowired
@Qualifier("jioBean")
private Sim sim;

  • IoC = Spring controls objects

  • DI = Spring injects dependencies

  • XML = old method

  • Java config = better

  • Annotation = best (used in Spring Boot)

"In Spring Boot, IoC container manages bean lifecycle and dependency injection using annotations like @Component and @Autowired, which helps in loose coupling and better maintainability."

spring IOC | Spring Boot | Softcrayons Tech Solutions