Lecture 29: Introduction to Design Patterns in Spring

BMC201 - Web Technology

Mr. Prashant Kumar Nag

2026-03-13

Lecture 29

Introduction to Design Patterns in Spring

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

Learning Objectives


  • Explain role of design patterns in Spring
  • Map core patterns to framework components
  • Select patterns for maintainability

Prerequisites


  • Core Java OOP concepts and interface-based design
  • Basic understanding of Servlets/JSP request flow from Unit III
  • Revision of Lecture 28 before moving into Introduction to Design Patterns in Spring

Syllabus Mapping


  • Unit IV topic focus: Introduction to Design Patterns in Spring
  • CO alignment: implementation understanding + architecture reasoning
  • Assessment alignment: short definitions + long implementation/design questions

Agenda


  • 5-minute recap from previous lecture
  • Concept deep dive: Introduction to Design Patterns in Spring
  • Code/configuration walkthrough and output analysis
  • Debug checklist and exam-oriented summary

Introduction


Spring uses multiple patterns to stay extensible and testable.

Think About It


Which pattern centralizes object creation?

What Are Design Patterns?


Design Patterns are reusable solutions to commonly occurring problems in software design.

They provide:

  • Proven solutions — tested approaches that work
  • Common vocabulary — shared language for developers
  • Best practices — accumulated wisdom from experienced developers
  • Flexible design — adaptable to different contexts

Design patterns are not code templates but conceptual solutions.

Why Design Patterns Matter in Spring


Spring Framework is built on design patterns:

  • Maintainability — patterns make code easier to understand and modify
  • Extensibility — new features integrate cleanly using established patterns
  • Testability — patterns like Dependency Injection enable easy testing
  • Scalability — proven patterns handle growth gracefully

Understanding patterns helps you leverage Spring’s power effectively.

GoF Pattern Categories


Gang of Four (GoF) patterns fall into three categories:

Creational Patterns — Object creation mechanisms - Factory, Abstract Factory, Singleton, Builder, Prototype

Structural Patterns — Object composition and relationships - Proxy, Adapter, Decorator, Composite, Facade

Behavioral Patterns — Communication between objects - Template Method, Strategy, Observer, Command, Iterator

Core Patterns in Spring Framework


Spring extensively uses several key patterns:

Pattern Purpose in Spring Example
Factory Create beans dynamically BeanFactory, ApplicationContext
Singleton Single instance per container Default bean scope
Proxy Add behavior dynamically AOP, Transactions, Lazy loading
Template Method Define algorithm skeleton JdbcTemplate, RestTemplate
Dependency Injection Invert control flow @Autowired, Constructor injection

Factory Pattern in Spring


Factory Pattern provides an interface for creating objects without specifying exact classes.

Spring’s Implementation:

  • BeanFactory — basic container for bean creation
  • ApplicationContext — advanced factory with enterprise features
  • FactoryBean<T> — custom bean creation logic
ApplicationContext ctx = 
    new AnnotationConfigApplicationContext(AppConfig.class);
UserService service = ctx.getBean(UserService.class);

Spring’s IoC container is essentially a sophisticated factory.

Singleton Pattern in Spring


Singleton Pattern ensures only one instance of a class exists.

Spring’s Implementation:

  • Default scope for all beans is singleton
  • Container manages the single instance
  • Thread-safe creation and caching
@Component  // singleton by default
public class ConfigurationService {
    // Only one instance created per container
}

Spring’s singleton is per-container, not per-JVM like classic singleton.

Proxy Pattern in Spring


Proxy Pattern provides a surrogate that controls access to another object.

Spring’s Implementation:

  • AOP proxies — add cross-cutting concerns (logging, security)
  • Transaction proxies — wrap methods with transaction boundaries
  • Lazy-loading proxies — defer object creation until needed
@Transactional  // Spring creates proxy with transaction logic
public void saveUser(User user) {
    userRepository.save(user);
}

Spring uses JDK dynamic proxies or CGLIB proxies automatically.

Template Method Pattern in Spring


Template Method defines algorithm structure, allowing subclasses to override specific steps.

Spring’s Implementation:

  • JdbcTemplate — eliminates JDBC boilerplate
  • RestTemplate — simplifies REST client code
  • JmsTemplate — reduces JMS complexity
List<User> users = jdbcTemplate.query(
    "SELECT * FROM users",
    (rs, rowNum) -> new User(rs.getLong("id"), rs.getString("name"))
);

Template classes handle resource management; you provide business logic.

Dependency Injection Pattern


Dependency Injection (DI) is a specialization of Inversion of Control.

Instead of objects creating dependencies, they receive them:

// Without DI (tight coupling)
class OrderService {
    private PaymentGateway gateway = new PaymentGateway();
}

// With DI (loose coupling)
@Service
class OrderService {
    private final PaymentGateway gateway;
    
    @Autowired
    public OrderService(PaymentGateway gateway) {
        this.gateway = gateway;
    }
}

Benefits of Pattern-Based Design


Why patterns improve Spring applications:

  1. Code Reusability — common solutions across projects
  2. Easier Communication — “we need a factory here” is understood
  3. Proven Architecture — patterns have stood the test of time
  4. Better Testing — patterns enable mocking and isolation
  5. Predictable Structure — new developers recognize familiar patterns
  6. Flexibility — change implementations without changing interfaces

Patterns provide a shared mental model for the team.

Identifying Patterns in Spring Code


How to recognize patterns in Spring applications:

Factory → Classes with create(), build(), or getBean() methods

Singleton@Component, @Service, @Repository without explicit scope

Proxy@Transactional, @Async, @Cacheable annotations

Template Method → Classes ending in Template (JdbcTemplate)

Strategy → Multiple implementations of same interface with @Qualifier

Pattern Landscape


flowchart TD
    A["Spring Container"] --> B["Factory Pattern\nBean Creation"]
    A --> C["Singleton Pattern\nBean Scope"]
    A --> D["Proxy Pattern\nAOP/Transactions"]
    A --> E["Template Method\nJdbcTemplate/RestTemplate"]
    B --> F["Flexible Object Creation"]
    C --> F
    D --> F
    E --> F
    F --> G["Maintainable Spring Applications"]

Spring combines multiple patterns to achieve loose coupling and flexibility.

How Patterns Work Together


Patterns in Spring often collaborate:

Factory + Singleton:

// Factory creates singleton beans
ApplicationContext ctx = new AnnotationConfigApplicationContext();
UserService service = ctx.getBean(UserService.class); // singleton

Proxy + Template Method:

@Transactional // Proxy wraps this method
public void processOrder(Order order) {
    jdbcTemplate.update(...); // Template simplifies JDBC
}

Code Walkthrough: Pattern Usage


// Factory: ApplicationContext creates beans
@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {  // Factory method
        return new HikariDataSource();
    }
}

// Singleton: Default scope
@Service
public class NotificationService { }

// Proxy: AOP adds behavior
@Transactional
public void updateUser(User user) { }

// Template Method: JdbcTemplate
jdbcTemplate.query("SELECT * FROM users", 
    new UserRowMapper());

Pattern Selection Best Practices


Guidelines for using patterns in Spring:

  1. Don’t force patterns — use them when they solve real problems
  2. Understand the intent — know why a pattern exists, not just how
  3. Keep it simple — patterns should simplify, not complicate
  4. Leverage Spring’s patterns — don’t reinvent what Spring provides
  5. Document unusual patterns — explain why you chose a pattern
  6. Refactor to patterns — start simple, introduce patterns as needed

Patterns are tools, not goals. Use them judiciously.

Common Anti-Patterns to Avoid


Pattern Overload — using patterns when simple code would work

// OVERKILL: Factory for trivial object
class StringFactory {
    public String create() { return new String(); }
}

Service Locator — looking up dependencies manually

// AVOID: Defeats DI benefits
UserService service = ServiceLocator.getService(UserService.class);

Let Spring manage dependencies; avoid manual lookups.

Real-World Pattern Example


@Configuration
public class PaymentConfig {
    @Bean
    public PaymentProcessorFactory processorFactory() {
        return new PaymentProcessorFactory();  // Factory
    }
}

@Service
public class OrderService {  // Singleton
    private final PaymentProcessorFactory factory;
    
    @Autowired
    public OrderService(PaymentProcessorFactory factory) {
        this.factory = factory;  // Dependency Injection
    }
    
    @Transactional  // Proxy
    public void checkout(Order order) {
        PaymentProcessor processor = factory.create(order.getMethod());
        processor.process(order.getAmount());
    }
}

Memory Booster


Syllabus memory points for Introduction to Design Patterns in Spring:

  • Core recall: Factory, Proxy, Singleton, Template Method usage
  • Exam compare: Pattern-based architecture vs ad-hoc implementation
  • Practical anchor: Identify and justify pattern usage in a Spring component

Live Demo


Live implementation for Introduction to Design Patterns in Spring:

?? Open Demo: Lecture 29 - Introduction to Design Patterns in Spring

Demo checklist: - implement the key flow for this lecture - verify expected output for one success case - trigger one failure case and explain the fix

Resources & References


Structured Debug Checklist


  1. verify the primary API usage for Introduction to Design Patterns in Spring is correct (imports, method names, config)
  2. check request/bean/session flow and object lifecycle assumptions
  3. inspect server logs for the first exception (not just the final symptom)
  4. reproduce one failing case and one passing case before finalizing fixes

Exam Preparation Questions: Short


  • Define Introduction to Design Patterns in Spring with one practical use case.
  • Write/identify the key API or construct: Factory, Proxy, Singleton, Template Method usage.
  • Differentiate: Pattern-based architecture vs ad-hoc implementation.
  • Mention one common implementation error and correction.

Exam Preparation Questions: Long


  • Explain Introduction to Design Patterns in Spring with architecture/flow and implementation steps.
  • Write a structured answer comparing two approaches used in this topic.
  • Discuss debugging strategy for this topic with likely failure points.

Practice Task


  • Implement: Identify and justify pattern usage in a Spring component.
  • Add console/log output to validate flow step-by-step.
  • Document one bug you encountered and the exact fix.

Checklist


Can you:

  • explain Introduction to Design Patterns in Spring in your own words?
  • implement a basic example end-to-end?
  • identify and fix one common runtime issue?

Next Lecture


  • Topic: Lecture 30 - Factory Design Pattern in Spring
  • Preparation required: revise this lecture summary and code walkthrough

Questions?

Next: Lecture 30