Spring Boot

Spring Initializer

20 min

Spring Initializer

Tutorial 13: Spring Initializer Deep Dive 🚀

📋 Table of Contents

  1. Understanding the Question
  2. What Spring Initializer Does
  3. Starter Selection Strategy
  4. Understanding Generated Projects
  5. Customization
  6. Best Practices
  7. Practice Questions

Understanding the Question ❓

What are we trying to achieve?

Spring Initializer (start.spring.io) is a project scaffolding tool. It answers:

  • How do I set up a new Spring Boot project?
  • Which dependencies do I need?
  • What's the minimal, correct structure?
  • How do I avoid configuration mistakes?

Without Spring Initializer

text
❌ MANUAL PROJECT SETUP (Error-prone, time-consuming):

1. Create Maven project structure manually
   ├── src/main/java
   ├── src/main/resources
   ├── src/test/java
   └── pom.xml

2. Write pom.xml from scratch:
   - Add Spring Boot parent
   - Add all needed dependencies
   - Handle version conflicts
   - Configure plugins

3. Create application.yml
   - What properties are available?
   - Which ones are required?

4. Create @SpringBootApplication class
   - Where does it go?
   - What annotations?

5. Discover you forgot a dependency
   - Spend hours debugging

With Spring Initializer

text
✅ AUTOMATED PROJECT SETUP (Correct, instant):

1. Go to start.spring.io
2. Select starters you need
3. Click Generate
4. Extract zip file
5. Done! Working project

✅ Benefits:
- No version conflicts
- Correct folder structure
- Automatic dependency management
- Best practices pre-configured
- Works immediately

What Spring Initializer Does

Behind the Scenes

text
Spring Initializer → Generates → Customized Project Based On:
                     ├── Spring Boot Version (3.x, 2.x)
                     ├── Project Type (Maven, Gradle)
                     ├── Language (Java, Kotlin, Groovy)
                     ├── Packaging (JAR, WAR)
                     ├── Java Version (17, 21)
                     ├── Selected Starters (Web, Data JPA, Security, etc.)
                     └── Build Tool Configuration

What Gets Generated

text
myapp/
├── pom.xml                          ← Maven configuration
├── mvnw / mvnw.cmd                  ← Maven wrapper (no installation needed!)
├── .gitignore                       ← For version control
├── README.md                        ← Basic documentation
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/example/myapp/
│   │   │       └── MyappApplication.java    ← Main @SpringBootApplication class
│   │   └── resources/
│   │       └── application.yml              ← Configuration file
│   └── test/
│       ├── java/
│       │   └── com/example/myapp/
│       │       └── MyappApplicationTests.java   ← Test class template
│       └── resources/
└── target/                          ← Build output (generated)

Key Files Explained:

1. pom.xml - Defines project structure and dependencies
2. mvnw - Maven wrapper script (lets you run mvn without installing Maven)
3. application.yml - Spring Boot configuration template
4. MyappApplication.java - Entry point with @SpringBootApplication

The Generated pom.xml

xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
    <!-- Define this project -->
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>myapp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>myapp</name>
    <description>Demo project for Spring Boot</description>

    <!-- Parent pom provides default configuration -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.1</version>
        <relativePath/>
    </parent>

    <!-- Define Java version -->
    <properties>
        <java.version>17</java.version>
    </properties>

    <!-- Dependencies - Starters you selected -->
    <dependencies>
        <!-- Spring Boot Web Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring Boot Data JPA Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- H2 Database (for dev/test) -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- Spring Boot Test Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!-- Build configuration -->
    <build>
        <plugins>
            <!-- Spring Boot Maven Plugin -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

The Generated Application Class

java
package com.example.myapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @SpringBootApplication combines three annotations:
 * 1. @Configuration - This is a Spring configuration class
 * 2. @EnableAutoConfiguration - Enable Spring Boot's auto-configuration
 * 3. @ComponentScan - Find @Components in this package and subpackages
 */
@SpringBootApplication
public class MyappApplication {

    // Entry point - starts the entire Spring Boot application
    public static void main(String[] args) {
        SpringApplication.run(MyappApplication.class, args);
    }
}

The Generated Test Class

java
package com.example.myapp;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * Template for integration tests
 * @SpringBootTest loads entire Spring context
 */
@SpringBootTest
class MyappApplicationTests {

    @Test
    void contextLoads() {
        // This test just verifies Spring context loads without errors
    }
}

Starter Selection Strategy

Understanding Starters

A Starter is a pre-configured set of dependencies for a specific purpose:

text
spring-boot-starter-web
    ├── spring-webmvc
    ├── spring-web
    ├── embedded-tomcat
    ├── jackson-json
    └── validation

Instead of adding 5 dependencies manually, you add 1 starter!

Common Starters and When to Use Them

text
FOR REST APIS / WEB APPLICATIONS:
├── spring-boot-starter-web
│   └── Use for: REST APIs, MVC web applications, anything with @RestController
├── spring-boot-starter-webflux
│   └── Use for: High-throughput, non-blocking APIs, reactive programming

FOR DATA ACCESS:
├── spring-boot-starter-data-jpa
│   └── Use for: SQL databases with ORM (MySQL, PostgreSQL)
├── spring-boot-starter-data-mongodb
│   └── Use for: MongoDB NoSQL database
├── spring-boot-starter-data-redis
│   └── Use for: Redis caching and in-memory data structure store
├── spring-boot-starter-data-elasticsearch
│   └── Use for: Elasticsearch full-text search

FOR SECURITY:
├── spring-boot-starter-security
│   └── Use for: Authentication, authorization, CSRF protection
├── spring-boot-starter-oauth2-resource-server
│   └── Use for: OAuth2 resource servers

FOR INTEGRATION:
├── spring-boot-starter-amqp
│   └── Use for: Message queues (RabbitMQ)
├── spring-boot-starter-kafka
│   └── Use for: Apache Kafka event streaming

FOR MONITORING:
├── spring-boot-starter-actuator
│   └── Use for: Health checks, metrics, endpoints

FOR CLOUD:
├── spring-cloud-starter-config
│   └── Use for: External configuration management
├── spring-cloud-starter-service-registry
│   └── Use for: Service discovery (Eureka, Consul)

FOR TEMPLATES:
├── spring-boot-starter-freemarker
├── spring-boot-starter-thymeleaf
│   └── Use for: HTML template engines (if building MVC web applications)

Decision Tree for Starters

text
                        START
                        ├─────────────────────────────────┐
                    Building what?
                   ↙         ↓        ↘
              REST API    MVC App   Microservice
                ↓            ↓         ↓
            spring-       spring-   spring-
            boot-          boot-    boot-
            starter-       starter- starter-
            web            web      web +
                                   spring-cloud-*
                ↓              ↓           ↓
            Need data?    Need data?    Need message?
            Y/N           Y/N          Y/N
            ↓             ↓            ↓
         Add:          Add:         Add:
      spring-       spring-    spring-boot-
      boot-         boot-      starter-
      starter-      starter-   kafka
      data-jpa      data-jpa
           ↓            ↓
        Database?    Template?
        Y/N          Y/N
           ↓            ↓
      Add:           Add:
    postgres /    thymeleaf
    h2/mysql

Example Selections for Common Projects

text
1. Simple REST API with Database:
   ✓ Spring Boot Starter Web
   ✓ Spring Boot Starter Data JPA
   ✓ MySQL Driver (or PostgreSQL)
   ✓ Spring Boot Starter Test

2. Microservice with Authentication:
   ✓ Spring Boot Starter Web
   ✓ Spring Boot Starter Security
   ✓ Spring Boot Starter Data JPA
   ✓ Spring Cloud Starter Config
   ✓ Spring Cloud Starter Service Registry
   ✓ PostgreSQL Driver

3. Real-Time Event Processing:
   ✓ Spring Boot Starter Kafka
   ✓ Spring Boot Starter Data Redis
   ✓ Spring Boot Starter Test

4. Full-Stack Web Application:
   ✓ Spring Boot Starter Web
   ✓ Spring Boot Starter Thymeleaf
   ✓ Spring Boot Starter Data JPA
   ✓ Spring Boot Starter Security
   ✓ H2 Database (development)
   ✓ PostgreSQL Driver (production)

5. Batch Processing Application:
   ✓ Spring Boot Starter Batch
   ✓ Spring Boot Starter Data JPA
   ✓ PostgreSQL Driver
   ✓ Spring Boot Starter Logging

Understanding Generated Projects

What Happens When You Run the App

text
java -jar myapp.jar

1. Spring loads your main class (MyappApplication)
2. Detects @SpringBootApplication annotation
3. Loads all auto-configuration classes
4. Creates application context
5. Starts embedded Tomcat server
6. Binds to port 8080 (default)
7. Ready to accept HTTP requests!

All in ~2 seconds typically!

Project Structure Best Practices

text
com/example/myapp/
├── MyappApplication.java           ← Main class
├── config/                         ← Configuration classes
│   ├── SecurityConfig.java
│   └── DatabaseConfig.java
├── controller/                     ← @RestController classes
│   ├── UserController.java
│   └── ProductController.java
├── service/                        ← @Service classes (business logic)
│   ├── UserService.java
│   └── ProductService.java
├── repository/                     ← @Repository classes (data access)
│   ├── UserRepository.java
│   └── ProductRepository.java
├── entity/ or domain/              ← JPA entities
│   ├── User.java
│   └── Product.java
├── dto/                            ← Data Transfer Objects
│   ├── UserRequest.java
│   └── UserResponse.java
├── exception/                      ← Custom exceptions
│   ├── ResourceNotFoundException.java
│   └── GlobalExceptionHandler.java
└── util/                           ← Utility classes
    └── ValidationUtil.java

Running the Generated Project

bash
# Navigate to project directory
cd myapp

# Option 1: Using Maven wrapper (included!)
./mvnw spring-boot:run

# Option 2: Build and run jar
./mvnw clean package
java -jar target/myapp-0.0.1-SNAPSHOT.jar

# Option 3: Run in IDE
# Right-click MyappApplication.java → Run

# Option 4: Command line with parameters
java -jar target/myapp.jar --server.port=9000 --spring.profiles.active=prod

Customization

Modifying After Generation

java
// 1. Add custom properties to application.yml
spring:
  application:
    name: my-awesome-app
  datasource:
    url: jdbc:mysql://localhost/mydb

app:
  name: My App
  version: 1.0.0

// 2. Add your first REST endpoint
@RestController
@RequestMapping("/api/hello")
public class HelloController {

    @GetMapping
    public Map<String, String> hello() {
        return Map.of("message", "Hello from Spring Boot!");
    }
}

// 3. Create database entities
@Entity
@Table(name = "users")
@Data
public class User {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String email;
}

// 4. Create repository
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    User findByEmail(String email);
}

// 5. Create service
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public User createUser(String name, String email) {
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        return userRepository.save(user);
    }
}

// 6. Create controller endpoint
@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping
    public User createUser(@RequestBody UserRequest request) {
        return userService.createUser(request.getName(), request.getEmail());
    }
}

Best Practices

✅ DO: Choose Starters First, Not Dependencies

java
// ✅ Good - Select "Spring Boot Starter Web" from Initializer
// pom.xml automatically gets spring-webmvc, spring-web, tomcat, jackson, etc.

// ❌ Bad - Adding individual dependencies manually
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
</dependency>
// ... more manual work, higher chance of version conflicts

✅ DO: Use Latest Long-Term Support (LTS) Version

java
// Choose from: 2.7.x (LTS), 3.2.x (LTS), 3.3.x (latest)
// Avoid: 3.0.x, 3.1.x (not LTS - will go out of support)

❌ DON'T: Add Unnecessary Starters

java
// ❌ Bad - Starter for something you don't need
// ✓ Spring Boot Starter Web
// ✓ Spring Boot Starter Data JPA
// ✓ Spring Boot Starter Actuator
// ✓ Spring Boot Starter Freemarker  ← Don't need this for REST API!

// ✅ Good - Only what you actually use
// ✓ Spring Boot Starter Web
// ✓ Spring Boot Starter Data JPA
// ✓ Spring Boot Starter Actuator

✅ DO: Keep Generated Structure

text
The Initializer gives you a proven structure.
Use it! Don't over-engineer.

Bad example:
myapp/
├── api/               ← Over-layered
├── business/
├── persistence/
├── util/
├── ...

Good example (Initializer default):
myapp/
├── config/
├── controller/
├── service/
├── repository/
├── entity/
└── ...

Practice Questions

Question 1: What's the Difference Between a Starter and a Dependency?

Q: Why should I choose "Spring Boot Starter Web" instead of just adding individual dependencies?

A: A Starter is a curated set of compatible dependencies. It saves you from:

  • Version conflicts
  • Missing transitive dependencies
  • Configuration mistakes
java
// Starter = 1 dependency that pulls in many
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

// vs. manual = many dependencies you have to manage
<dependency><artifactId>spring-webmvc</artifactId></dependency>
<dependency><artifactId>spring-web</artifactId></dependency>
<dependency><artifactId>tomcat-embed-core</artifactId></dependency>
// ... and 10 more

Question 2: Can You Remove Starters After Generation?

Q: I selected the Actuator starter but don't actually need it. Can I remove it?

A: Yes! Just delete it from

text
pom.xml
. Spring Boot won't load Actuator endpoints if the dependency isn't present:

xml
<!-- Just remove this entire dependency -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- Then rebuild -->
./mvnw clean package

Question 3: What Does Maven Wrapper Do?

Q: What's the

text
mvnw
script and why is it included?

A: Maven Wrapper lets you run Maven without installing it globally:

bash
# Traditional way (requires Maven installed)
mvn clean package

# Maven Wrapper way (included in project)
./mvnw clean package  # Downloads correct Maven version if needed

# Benefits:
# - Exact Maven version, works on any machine
# - No "works on my machine" problems
# - Team uses same build tool version

Key Takeaways

  1. Spring Initializer is your starting point: Always use start.spring.io for new projects
  2. Select starters, not individual dependencies: Starters manage compatibility
  3. Start with the minimum: Add starters as you need them
  4. Generated structure is proven: Follow the folder organization pattern
  5. Maven wrapper handles build: Use
    text
    ./mvnw
    instead of
    text
    mvn
  6. All configuration files are templates: Customize them for your needs
  7. Use LTS versions: Spring Boot 2.7.x or 3.2.x are stable
  8. Generated test class is a template: Use it as starting point for tests
  9. Spring Initializer prevents mistakes: Version conflicts, missing dependencies, wrong structure
  10. You can add/remove starters anytime: Not locked into initial selection
Press j for next, k for previous