Lecture 33: Spring Core Basics & Dependency Injection

BMC201 - Web Technology

Mr. Prashant Kumar Nag

2026-03-19

Lecture 33

Spring Core Basics & Dependency Injection

Week 9 | Unit IV: Spring Framework
BMC201 - Web Technology
Mr. Prashant Kumar Nag, Assistant Professor

Learning Objectives


  • Explain what the Spring Framework is and why it is used
  • Describe Inversion of Control (IoC) in plain English
  • Differentiate constructor injection, setter injection, and field injection
  • Write a basic Spring configuration using Java annotations
  • Use ApplicationContext to retrieve and use beans
  • Recognize when Spring DI reduces tight coupling in code

What is the Spring Framework?


Spring is a lightweight Java application framework for building enterprise-grade applications.

Core goals: - Remove tight coupling between classes - Manage object creation and wiring automatically - Provide clean structure for large applications

Spring offers a complete ecosystem: Core, MVC, Data, Security, Boot, Cloud.

Tight Coupling Problem


// Without DI — tightly coupled
public class OrderService {
  private PaymentService payment = new PaymentService(); // #<1>
  private EmailService email = new EmailService();       // #<2>
}

// With DI — loosely coupled
public class OrderService {
  private PaymentService payment; // #<3>
  private EmailService email;     // #<4>
  public OrderService(PaymentService p, EmailService e) {
    this.payment = p; this.email = e;
  }
}
  1. Hard-coded dependency — cannot swap implementation
  2. Hard-coded dependency — cannot mock in tests
  3. Injected from outside — any implementation works
  4. Injected from outside — testable and flexible

Inversion of Control (IoC)


IoC means the framework controls object creation, not your code.

Without IoC → you create objects
With IoC → Spring creates objects and injects dependencies

The Spring IoC container is called the ApplicationContext.

flowchart LR
  A[Configuration Metadata] --> B[Spring IoC Container]
  C[POJO Classes] --> B
  B --> D[Ready-to-use Application Objects]

ApplicationContext vs BeanFactory


Feature BeanFactory ApplicationContext
Bean initialization Lazy (on demand) Eager at startup
Event publishing No Yes
i18n support No Yes
Annotation support Limited Full
Recommended for Unit testing All applications

In practice, always use ApplicationContextBeanFactory is rarely used directly.

Constructor Injection


@Component
public class OrderService {
  private final PaymentService paymentService; // #<1>
  private final EmailService emailService;

  @Autowired                                   // #<2>
  public OrderService(PaymentService p, EmailService e) {
    this.paymentService = p;
    this.emailService   = e;
  }
}
  1. final fields — guarantees immutability after creation
  2. @Autowired tells Spring to inject matching beans here

Constructor injection is preferred — makes dependencies explicit and supports immutability.

Setter Injection


@Component
public class ReportService {
  private DataSource dataSource;

  @Autowired
  public void setDataSource(DataSource ds) { // #<1>
    this.dataSource = ds;
  }
}
  1. Spring calls this setter with the matching bean after construction

Use setter injection for optional dependencies or when circular dependency exists.

Field Injection (and Why to Avoid It)


@Component
public class UserService {
  @Autowired
  private UserRepository repo; // #<1>
}
  1. Spring injects directly into the field — no constructor or setter needed

Appears simple but has problems:

  • Cannot make fields final
  • Hard to test without Spring container
  • Hides dependencies (not visible from outside)

Prefer constructor injection in production code.

Three Configuration Styles


Spring supports three ways to define beans:

Style How When to Use
XML <bean id="..." class="..."/> Legacy projects
Java Config @Configuration + @Bean Full control over creation
Annotation @Component + @Autowired Most modern projects

All three styles can coexist in the same project.

Java Configuration Example


@Configuration                              // #<1>
public class AppConfig {

  @Bean                                     // #<2>
  public UserRepository userRepository() {
    return new UserRepositoryImpl();
  }

  @Bean
  public UserService userService() {
    return new UserService(userRepository()); // #<3>
  }
}
  1. Marks this class as Spring configuration source
  2. Method return value is registered as a Spring bean
  3. Spring calls this for the injected dependency

Annotation-Based Configuration


@SpringBootApplication                      // #<1>
public class App {
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
}

@Repository                                 // #<2>
public class UserRepositoryImpl implements UserRepository { ... }

@Service                                    // #<3>
public class UserService {
  @Autowired UserRepository repo;
}
  1. Component scan + auto-configuration enabled
  2. Spring detects and registers this as a bean
  3. Registers as service bean; repo injected automatically

Retrieving Beans from ApplicationContext


// XML-based context
ApplicationContext ctx =
  new ClassPathXmlApplicationContext("beans.xml");

// Java config context
ApplicationContext ctx =
  new AnnotationConfigApplicationContext(AppConfig.class);

// Retrieve bean
UserService svc = ctx.getBean(UserService.class); // #<1>
svc.processOrder();
  1. Spring returns the fully-wired bean instance

Common Mistakes to Avoid


  • Using new to create beans instead of letting Spring manage them
  • Mixing field injection everywhere instead of constructor injection
  • Forgetting @Component or @Bean so Spring cannot find the class
  • Using BeanFactory directly when ApplicationContext is available
  • Circular dependency due to two beans injecting each other via constructors

AKTU Exam-Oriented Checklist


Prepare these high-probability questions:

  1. Define Spring Framework and list its core modules
  2. Explain IoC with a diagram
  3. Differentiate constructor injection, setter injection, and field injection
  4. Compare ApplicationContext and BeanFactory
  5. Write a simple Spring Java configuration example

Summary


You now understand:

  • Spring as an IoC container managing object lifecycle
  • How dependency injection decouples components
  • Three injection styles and when to use each
  • Three configuration approaches (XML, Java, Annotation)
  • How to retrieve and use beans from ApplicationContext

Questions?

Next: Lecture 34 - Design Patterns: Factory & Strategy