Spring Boot

Deep Dive Comparison

30 min

Deep Dive Comparison

Tutorial 07: Boot vs Spring Deep Dive 🔍

📋 Table of Contents

  1. Core Differences
  2. Architecture Comparison
  3. Development Experience
  4. When to Choose Each
  5. Migration Path
  6. Real-World Implications

Core Differences

Spring Framework (Traditional)

Spring Framework is the foundational OOP framework for enterprise Java applications providing:

  • IoC Container for dependency management
  • AOP for cross-cutting concerns
  • MVC for web applications
  • Transaction management
  • Data access abstraction

Setup Burden:

xml
<!-- Hundreds of lines of configuration -->
<beans xmlns="http://www.springframework.org/schema/beans">
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="org.h2.Driver"/>
        <property name="url" value="jdbc:h2:mem:testdb"/>
        <property name="username" value="sa"/>
        <property name="password" value=""/>
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan">
            <list>
                <value>com.example.entity</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
                <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- More and more configuration... -->
</beans>

Spring Boot (Modern)

Spring Boot simplifies development with intelligent defaults and auto-configuration:

yaml
# That's it! Spring Boot handles everything else automatically
spring:
  datasource:
    url: jdbc:h2:mem:testdb
  jpa:
    hibernate:
      ddl-auto: create-drop

Key Philosophical Difference

Spring Framework Philosophy:

text
Explicit Configuration > Convention
Developer Controls Everything > Framework Defaults
Flexible but Complex > Powerful but Effort-Heavy

Spring Boot Philosophy:

text
Convention over Configuration > Explicit Configuration
Intelligent Defaults > Manual Setup
Fast Feedback Loop > Enterprise Reliability (Still There!)

Architecture Comparison

Traditional Spring Web Application

text
Developer Creates:
├── pom.xml (50+ dependencies, version management)
├── web.xml (servlet configuration)
├── applicationContext.xml (bean definitions)
├── mvc-config.xml (MVC configuration)
├── security-config.xml (security beans)
├── persistence-config.xml (database config)
└── deploy to: Tomcat/JBoss/WebLogic (separate)

Framework Provides:
├── Dependency Injection
├── AOP
├── Transaction Management
└── Basic MVC

Developer Must Provide:
├── Server deployment
├── Logging setup
├── Monitoring
├── Health checks
└── Graceful shutdown

Spring Boot Application

text
Developer Creates:
├── pom.xml (spring-boot-starter-*)
├── @SpringBootApplication class
└── application.yml (properties)

Spring Boot Auto-Provides:
├── Embedded server (Tomcat/Jetty/Undertow)
├── Auto-configuration (99% of needs)
├── Logging (SLF4J + Logback)
├── Actuator (health, metrics, monitoring)
├── Error handling
├── Graceful shutdown
└── Production-ready defaults

Developer Can Override:
├── Auto-configuration selectively
├── Add custom beans
└── Configure via properties

Development Experience

Setting Up Traditional Spring Application

Step 1: Create Project Structure

text
project/
├── src/main/webapp/WEB-INF/
│   └── web.xml
├── src/main/resources/
│   ├── applicationContext.xml
│   ├── applicationContext-mvc.xml
│   ├── applicationContext-security.xml
│   ├── applicationContext-persistence.xml
│   └── log4j.properties
└── src/main/java/com/example/...

Step 2: Configure Everything (web.xml)

xml
<web-app>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:applicationContext.xml
            classpath:applicationContext-mvc.xml
            classpath:applicationContext-persistence.xml
            classpath:applicationContext-security.xml
        </param-value>
    </context-param>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-mvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>

Step 3: Bean Configuration (XML Hell)

xml
<!-- applicationContext-persistence.xml -->
<beans>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <!-- 10 properties -->
    </bean>
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <!-- 15 properties -->
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <!-- 5 properties -->
    </bean>
</beans>

<!-- applicationContext-security.xml -->
<security:http>
    <security:intercept-url pattern="/**" access="ROLE_USER"/>
    <security:form-login login-page="/login" />
</security:http>

<!-- And more... -->

Step 4: Deploy

bash
mvn clean package
# Creates WAR file
# Copy to Tomcat webapps/
# Restart Tomcat
# Wait 30+ seconds for startup

Time to First API Call: 1-2 hours ⏱️


Setting Up Spring Boot Application

Step 1: Create Project

bash
# Option A: IDE template
File > New > Spring Starter Project > Select Dependencies > Create

# Option B: Command line
mvn spring-boot:run

Step 2: Single Java Class

java
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Step 3: One Configuration File

yaml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
  jpa:
    hibernate:
      ddl-auto: create-drop

Step 4: Run

bash
mvn spring-boot:run
# Embedded Tomcat starts
# Your app is ready
# 5-10 seconds total

Time to First API Call: 5-10 minutes


When to Choose Each

Use Traditional Spring When:

  1. Extreme Customization Needed

    • Every framework component needs tweaking
    • Industry-specific requirements
    • Example: Insurance company with custom risk assessment engine integrated deeply into Spring
  2. Legacy System Integration

    • Adding Spring to existing non-Spring app
    • Gradual migration needed
    • Example: Adding modern APIs to 10-year-old JSP application
  3. Custom Container Required

    • App deployed on legacy app server (WebLogic, JBoss)
    • Container-specific features needed
    • Example: Mainframe-connected banking system on proprietary server

Use Spring Boot When (99% of cases):

  1. New Applications

    • Starting fresh project
    • Microservices
    • Cloud-native applications
  2. Fast Time-to-Market

    • Startup velocity matters
    • MVP development
    • Proof of concepts
  3. Modern Stack

    • Docker containers
    • Kubernetes orchestration
    • Serverless (AWS Lambda)
  4. Team Productivity

    • Less configuration to understand
    • More time on business logic
    • Easier onboarding

Real-World Implications

Memory & Startup Time

Traditional Spring App on Tomcat:

text
Startup: 45 seconds
Memory: 500MB+ (JVM + Tomcat + Libraries)
Suitable for: Always-running servers

Spring Boot App:

text
Startup: 3-5 seconds
Memory: 150MB (Embedded Tomcat included)
Suitable for: Containers, Kubernetes, Serverless (cold start critical)

DevOps Perspective

Spring App:

  • Separate application server installation
  • Configuration management for app server
  • Multiple processes to manage
  • Complex Docker images
  • Slow deployments

Spring Boot App:

  • Single JAR file = complete application
  • No external dependencies
  • Docker:
    text
    COPY app.jar . && CMD ["java", "-jar", "app.jar"]
  • Fast deployments
  • Easy scaling

Operational Understanding

Spring (Complex Mental Model):

text
Developer writes:
  DispatcherServlet class

Framework provides:
  Request routing
  Bean creation
  Transaction handling

App server provides:
  Thread pool
  Connection pooling
  Classloading

Logs spread across:
  Tomcat logs
  Application logs
  Spring logs

Debugging requires:
  Understanding app server internals
  Spring internals
  Library internals

Spring Boot (Clear Model):

text
Developer writes:
  @RestController classes
  @Service classes

Spring Boot provides:
  EVERYTHING ELSE (app server, config, logging)

Single executable JAR = entire application

Logs in one place with consistent format

Debugging much simpler - less moving parts

Migration Path: Spring → Spring Boot

Phase 1: Parallel Setup

text
Keep running: Traditional Spring App on Tomcat
Start new: Spring Boot microservices for new features
Share: Database, message queues, cache

Phase 2: Gradual Service Migration

text
Identify low-risk services in Spring app
Extract to Spring Boot microservices
Route traffic through API gateway

Phase 3: Data Layer Separation

text
Extract shared database queries into separate service
Spring Boot service owns data
Spring app becomes client

Phase 4: Complete Migration

text
All business logic in Spring Boot services
Legacy app becomes optional wrapper (if needed)
Eventually decommission

🎯 Key Insights

  1. Spring is Powerful, Boot is Pragmatic - Spring does everything, Boot does it automatically
  2. Boot Simplifies the Common Path - 95% of projects need the same setup
  3. Boot Doesn't Remove Power - Just hides complexity when not needed
  4. Configuration Hell is Real - Spring XML configs are error-prone and verbose
  5. Modern Architecture Prefers Boot - Containers, Kubernetes, serverless all benefit from Boot's simplicity
  6. Developer Experience Matters - Boot lets developers focus on business logic

Interview Question

Q: Why did Spring Framework create Spring Boot instead of just improving Spring?

A: Spring Framework provides flexibility through explicit configuration. This is powerful but has downsides:

  • Configuration burden for simple apps
  • Lots of boilerplate
  • Steep learning curve
  • Slow feedback loop

Spring Boot takes a different philosophy:

  • Assume 95% of apps need similar setup
  • Auto-configure based on classpath
  • Provide sensible defaults
  • Let developers override when needed

Result: Same power, dramatically better developer experience for typical applications.


Changelog

  • 2025-11-23: Initial creation with deep architectural comparison
  • Added: Real-world implications and migration paths

Congratulations! You now deeply understand Boot vs Spring! 🎉

Press j for next, k for previous