Spring framework part 2.
Skilled in managing carrier-grade ISP infrastructure, enterprise environments, and server operations. Enthusiastic about optimizing high-performance networks and exploring emerging technologies. Committed to continuous learning and driven to leverage cloud solutions and automation tools to enhance innovation and efficiency.
Topics:
POJO
Tightly coupled
Loosely coupled
Dependency Injection and IOC(Inversion of control )
Bean
Application Context
Before diving into the Spring Framework, it’s helpful to first understand what a POJO is, and then gradually move on to other topics — this way, everything will make more sense.
A POJO (Plain Old Java Object) is a simple class that only contains private fields, public getters and setters, and sometimes constructors. It doesn't extend any special classes or implement specific interfaces — it's just a "plain" object used to store and transfer data.

public class Person {
private String name;
private int age;
// Constructor
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getter and Setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
In the above code the constructor initializes object attributes at creation, while getters and setters allow reading and updating those attributes later.
Now, let's understand the concepts of Tightly Coupled and Loosely Coupled.
| Tightly Coupled | Loosely Coupled |
| Objects are heavily dependent on each other. | Objects are independent and interact with minimal dependency. |
| Hard to modify or test individual components. | Easy to modify, test, and maintain code. |
| Changing one class often affects others. | Changing one class usually doesn't impact others. |

Tightly coupled example.
class Engine {
void start() {
System.out.println("Engine started");
}
}
class Car {
Engine engine = new Engine(); // Direct dependency
void startCar() {
engine.start();
}
}
In the tightly coupled example, the Car class creates its own Engine object internally, making it hard to change or replace the Engine without modifying the Car class itself.
Loosely Coupled example.
class Engine {
void start() {
System.out.println("Engine started");
}
}
class Car {
Engine engine;
Car(Engine engine) { // Engine passed from outside
this.engine = engine;
}
void startCar() {
engine.start();
}
}
In the loosely coupled example, the Engine object is passed into the Car class from outside (via constructor), making it flexible, easier to test, and maintain without changing the Car code.
Now, let's dive into Inversion of Control and Dependency Injection.
🔵 Inversion of Control (IoC):
IoC means giving control of creating and managing objects to someone else (like a framework), instead of the program handling it directly.
🔵 Dependency Injection (DI):
DI is a way to implement IoC where the required objects (dependencies) are given to a class from outside, rather than the class creating them itself.
Super Short Summary:
IoC = "Don't call us, we’ll call you."
DI = "I'll hand you what you need."Real-world Example:
Without IoC (Manual way):
You go to the kitchen, find ingredients, cook the food, and then eat.
→ You are doing everything yourself (full control).With IoC and DI:
You order food from a restaurant (like Swiggy or Zomato 🍔🚚).
The restaurant prepares the food and delivers it to you.
You just eat — you don’t worry about cooking or ingredients!
In a typical object-oriented design, classes often depend on other classes to function. Traditionally, we instantiate these dependent classes manually inside our design class, which leads to tight coupling and makes the system hard to test and maintain.
However, with Spring, we leverage Inversion of Control (IoC), where the control of object creation and dependency management is transferred to the Spring IoC container. This container automatically handles the instantiation, configuration, and lifecycle of dependent objects through Dependency Injection (DI). As a result, our code becomes loosely coupled, more modular, and easier to test and maintain.

class Food {
void prepare() {
System.out.println("Cooking food...");
}
}
class Person {
Food food = new Food(); // Person makes the food themselves
void eat() {
food.prepare();
System.out.println("Eating food");
}
}
👉 Here, Person is tightly coupled to Food.
They create and prepare the food themselves!
class Food {
void prepare() {
System.out.println("Food prepared and delivered!");
}
}
class Person {
Food food;
// Food is injected (maybe by a delivery guy! 😄)
Person(Food food) {
this.food = food;
}
void eat() {
food.prepare();
System.out.println("Eating delivered food");
}
}
public class Main {
public static void main(String[] args) {
Food orderedFood = new Food(); // Food prepared somewhere
Person person = new Person(orderedFood); // Injecting food
person.eat(); // Just eating!
}
}
✅ Summary:
Without IoC = You prepare your own food (tight coupling).
With IoC and DI = Someone else prepares food and gives it to you (loose coupling).
🔵 Bean in Java (especially in Spring):
A Bean is a simple Java object that is managed by a framework like Spring — it is created, configured, and injected automatically by the framework.
Simple words:
A bean = a Java object that Spring creates and manages for you.
@Component
class Food {
// Food class becomes a Bean
}
🔵 ApplicationContext in Spring:
ApplicationContext is the container in Spring that manages all the Beans — it creates them, wires them together, configures them, and handles their entire lifecycle.
Simple words:
It’s like Spring’s brain that knows which objects (Beans) exist and how they should be connected.
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Food food = context.getBean(Food.class);
Here, the context manages and gives you the Food Bean! in a java configuration file mention below.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public Food food() {
return new Food();
}
}
✅ Explanation:
@Configuration→ Marks this class as a configuration file for Spring.@Bean→ Tells Spring to create and manage aFoodobject as a Bean.
With the help of annotations in Spring Boot, our work becomes much easier and more convenient. However, understanding Spring Core is a necessary prerequisite.
Here’s a list of resources that helped me gain a deeper understanding of Spring Core.
https://www.youtube.com/watch?v=KcJ2mAYfjxU&list=PLhHaibdHQVE3EHm3w0r38x9oxESLbg-TV
And of course, Telusko’s videos, which tie everything together perfectly.
https://www.youtube.com/watch?v=If1Lw4pLLEo&t=2145s
Thank you and Happy Learning :)



