Showing posts with label #Object Oriented Programming with Java. Show all posts
Showing posts with label #Object Oriented Programming with Java. Show all posts

Mastering Spring Core – IoC & Dependency Injection (DI)

 

🌟 1. What is Spring Framework?

Spring Framework is a powerful, lightweight Java platform for building enterprise-grade applications. It provides a comprehensive infrastructure support for developing Java applications.

Main Goals:

  • Loose Coupling

  • Easy Testing

  • Better Code Maintainability

  • Integration with Web, Security, AOP, ORM, and Microservices (via Spring Boot)

🌀 2. What is Inversion of Control (IoC)?

📌 Definition:

Inversion of Control means transferring the control of object creation and dependency management to the Spring container, instead of manually creating objects using new keyword.

#BCS403,#Object Oriented Programming with Java



📦 Real-Life Analogy:

  • Without IoC: You go to a restaurant, go to the kitchen, cook food, serve yourself.

  • With IoC: You sit at a table and order. Chef (Spring container) serves you everything — you just consume.


🔧 Before Spring (Tightly Coupled Code):

public class Car {
    Engine engine = new Engine(); // tightly coupled
}

🌱 With Spring IoC (Loose Coupling):

public class Car {
    private Engine engine;

    public Car(Engine engine) { // injected via constructor
        this.engine = engine;
    }
}

And Spring container injects it for you.

🔗 3. What is Dependency Injection (DI)?

📌 Definition:

Dependency Injection is a design pattern used to achieve IoC. The object’s dependencies are injected by the container, not created manually.

✅ Types of Dependency Injection in Spring:

Type  Description    Use Case
Constructor DI  Dependencies are passed via constructor    Immutable objects
Setter DI  Dependencies injected via setter method    Optional dependencies
Field DI  Using annotations (@Autowired)    Quick setup

1️⃣ Constructor Injection (Constructor DI)

📌 Best for: Immutable dependencies (dependencies that shouldn’t change after object creation).

 Code Example:

🧩 Engine.java

 package com.example;


public class Engine {

    public void start() {

        System.out.println("🚀 Engine started via Constructor DI");

    }

}

🚗 Car.java
package com.example;

public class Car {
    private Engine engine;

    // Constructor DI
    public Car(Engine engine) {
        this.engine = engine;
    }

    public void drive() {
        engine.start();
        System.out.println("🏎️ Car is moving...");
    }
}

⚙️ applicationContext.xml

<bean id="engine" class="com.example.Engine"/>
<bean id="car" class="com.example.Car">
<constructor-arg ref="engine"/>
</bean>

▶️ Output:

🚀 Engine started via Constructor DI
🏎️ Car is moving...

2️⃣ Setter Injection (Setter DI)

📌 Best for: Optional or changeable dependencies

Code Example:

🧩 Engine.java

package com.example;
public class Engine {
public void start() {
System.out.println("🚀 Engine started via Setter DI");
}
}

🚗 Car.java
package com.example;

public class Car {
private Engine engine;

// Setter Method for Injection public void setEngine(Engine engine) { this.engine = engine; } public void drive() { engine.start(); System.out.println("🏎️ Car is moving..."); }
}

⚙️ applicationContext.xml
<bean id="engine" class="com.example.Engine"/>
<bean id="car" class="com.example.Car">
<property name="engine" ref="engine"/>
</bean>

▶️ Output:
🚀 Engine started via Setter DI
🏎️ Car is moving...

3️⃣ Field Injection (Annotation-Based @Autowired)

📌 Best for: Quick setup; not best for testing or immutability

Code Example:

🧩 Engine.java

package com.example;

import org.springframework.stereotype.Component;
@Component
public class Engine {
public void start() {
System.out.println("🚀 Engine started via Field DI");
}
}

🚗 Car.java

package com.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Car {
@Autowired
private Engine engine; // Field Injection
public void drive() {
engine.start();
System.out.println("🏎️ Car is moving...");
}
}

📄 Java Config – AppConfig.java
package com.example;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.example")
public class AppConfig {}

▶️ Main Class – App.java
package com.example;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Car car = context.getBean(Car.class);
car.drive();
}
}

▶️ Output:

🚀 Engine started via Field DI
🏎️ Car is moving...
🔍 Summary Table

DI Type Config Style Benefits        Drawbacks
Constructor DI XML / Java Config Immutable, recommended for required deps       More verbose if too many         dependencies

Setter DI XML / Java Config Good for optional properties    Allows mutation (not ideal for all cases)

Field DI Annotation-based Short and clean  Difficult to test, not           recommended for large apps

📘 4. How Spring Manages IoC and DI?

🔧 Spring provides a container called ApplicationContext, which:

  • Manages Beans

  • Injects Dependencies

  • Controls Bean Lifecycle

⚙️ 5. Let's Build a Simple Spring Core Project (Step-by-Step)
✅ Project Goal: Inject Engine object into Car using Spring

🛠 Step-by-Step (XML + Annotation Based DI)


🔶 STEP 1: Open Spring Initializr

  1. Go to: 👉 https://start.spring.io

  2. This is an official tool by Spring to generate a ready-to-use Spring Boot project.


🔶 STEP 2: Fill in Project Metadata

Fill the following fields:


Field  What to Fill
Project  Maven
Language  Java
Spring Boot  Keep latest version (e.g., 3.2.x)
Group  com.example
Artifact  spring-di-example
Name  spring-di-example
Description  Spring Boot project to demonstrate DI
Packaging  Jar
Java Version  17 or 21 (based on your system/IDE)

🔶 STEP 3: Add Dependencies

Click on the “ADD DEPENDENCIES” button and add:


  • ✅ Spring Web
  • ✅ Spring Context
  • ✅ Spring Boot DevTools (for hot reload in development)

🔶 STEP 4: Generate Project

Click the “GENERATE” button.
A .zip file will be downloaded → Unzip it on your computer.


🔶 STEP 5: Open Project in IDE

  1. Open IntelliJ IDEA, VS Code, or Eclipse.
  2. Select: File → Open → Navigate to unzipped folder → Open the folder
  3. Wait for the project to load and Maven to finish downloading dependencies.

🔶 STEP 6: Create Your Java Classes

Inside src/main/java/com/example/springdiexample/, create these files:

📁 Project Structure:

spring-core-example/
├── pom.xml
└── src/
└── main/
├── java/com/example/
│ ├── Engine.java
│ ├── Car.java
│ └── App.java
└── resources/
└── applicationContext.xml
📄 pom.xml

🔶 STEP 6: Create Your Java Classes

Inside src/main/java/com/example/springdiexample/, create these files:

📄 Engine.java
package com.example.springdiexample;

import org.springframework.stereotype.Component;
@Component
public class Engine {
public void start() {
System.out.println("🚀 Engine started via Constructor DI");
}
}

📄 Car.java
package com.example.springdiexample;

import org.springframework.stereotype.Component;

@Component
public class Car {
private final Engine engine;
// Constructor-based DI
public Car(Engine engine) {
this.engine = engine;
}
public void drive() {
engine.start();
System.out.println("🏎️ Car is moving via Spring Boot DI...");
}
}

🔶 STEP 7: Modify the Main Class

Open the auto-generated main class:

📄 SpringDiExampleApplication.java

package com.example.springdiexample;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringDiExampleApplication implements CommandLineRunner {
@Autowired
private Car car;
public static void main(String[] args) {
SpringApplication.run(SpringDiExampleApplication.class, args);
}
@Override
public void run(String... args) {
car.drive(); // This method runs after the app starts
}
}

🔶 STEP 8: Run Your Application

  1. Right-click on SpringDiExampleApplication.java

  2. Select Run

Output You’ll See in Console

🚀 Engine started via Constructor DI
🏎️ Car is moving via Spring Boot DI...

🎯 You Just Built a Spring Boot App!


And you used:

  • Spring Initializr to generate boilerplate code

  • @Component to register beans

  • Constructor Dependency Injection

  • @Autowired and CommandLineRunner to run code on startup






🔄 Quick Recap


StepTask
1Go to Spring Initializr
2Fill metadata and dependencies
3Generate and unzip project
4Open in IDE
5Create Engine, Car class
6Modify main class with DI
7Run and see output

🎯 Benefits of This Flow


FeatureWhy it helps?
Spring Initializr           No manual setup, production-ready base
@Component        Bean auto-registration
Constructor DI      Clean and testable
CommandLineRunner      Code runs at startup – great for testing

📚 Important Interview/Exam Questions

  1. What is Inversion of Control in Spring? Explain with example.

  2. What are the types of Dependency Injection? Which is preferred and why?

  3. Difference between BeanFactory and ApplicationContext?

  4. What is the role of @Autowired?

  5. How is Spring loosely coupled?

  6. What is the difference between XML vs Annotation based configuration?

  7. What is the life cycle of a Spring bean?