# Spring Boot Fundamentals (Deep dive for beginners)

Welcome — this is **Chapter 1** of a beginner-friendly, deep-dive mini-course on **Spring Boot**. We'll cover everything you need to get started: what Spring Boot is, how to install Java/IntelliJ/Maven on Windows/Ubuntu/macOS, creating a project (Spring Initializr + IntelliJ), Maven basics, the standard project structure, how `@SpringBootApplication` works (IOC / DI), and a step-by-step REST API CRUD example using Spring Boot + H2. I’ll keep explanations concrete and show small, copy-pasteable code examples.

---

## What is Spring Boot? (short deep dive)

**Spring Boot** is an opinionated framework built on top of the Spring ecosystem that makes it fast and straightforward to build production-ready applications. It:

* **Auto-configures** components for common use-cases so you don't write boilerplate configuration.
    
* Provides **starters** (e.g., `spring-boot-starter-web`) that bring together common dependencies.
    
* Runs with an **embedded server** (Tomcat by default) so you can run apps as standalone JARs.
    
* Includes developer conveniences (DevTools), metrics and health checks (Actuator), and easy packaging via Maven/Gradle plugins.
    

Why use Spring Boot? it lets you focus on business logic instead of wiring up servers, servlet containers, or complicated XML configs.

---

## Prerequisites for this chapter

* Basic familiarity with Java (classes, annotations).
    
* A computer (Windows / Ubuntu / macOS).
    
* Terminal/command-line comfort.
    
* We'll use Java 17+ (LTS) or newer. Spring Boot 3+ requires Java 17+.
    

---

## 1\. Install Java & IntelliJ (Windows / Ubuntu / macOS)

Below are practical, stable options. After each install, verify with `java -version`.

### Windows (recommended)

1. **Download JDK**
    
    * Go to Eclipse Temurin / Adoptium / Oracle and download the Windows x64 installer for Java 17+ (Temurin is free and commonly used).
        
    * Run the installer and follow steps.
        
2. **Set JAVA\_HOME (if installer didn’t)**
    
    * Open *System Properties → Advanced → Environment Variables*.
        
    * Add `JAVA_HOME` = `C:\Program Files\...temurin-17...` (path where JDK installed).
        
    * Add `%JAVA_HOME%\bin` to `Path`.
        
3. **Install IntelliJ IDEA**
    
    * Download IntelliJ Community (free) or Ultimate (paid) from JetBrains and run the installer.
        
    * Alternatively use Windows package managers: `winget` or `choco` (if you use them).
        
4. **Verify**
    
    ```bash
    java -version
    ```
    

---

### Ubuntu / Debian (recommended commands)

1. **Install OpenJDK 17** (example)
    
    ```bash
    sudo apt update
    sudo apt install openjdk-17-jdk -y
    ```
    
    Or use SDKMAN to manage versions (recommended if you try many versions):
    
    ```bash
    curl -s "https://get.sdkman.io" | bash
    source "$HOME/.sdkman/bin/sdkman-init.sh"
    sdk install java 17.0.8-tem
    ```
    
2. **Install IntelliJ**
    
    * Snap:
        
        ```bash
        sudo snap install intellij-idea-community --classic
        ```
        
    * Or use JetBrains Toolbox app.
        
3. **Verify**
    
    ```bash
    java -version
    ```
    

---

### macOS

1. **Install JDK** (Homebrew or SDKMAN)
    
    * Homebrew (Temurin):
        
        ```bash
        brew install --cask temurin
        ```
        
    * SDKMAN:
        
        ```bash
        curl -s "https://get.sdkman.io" | bash
        sdk install java 17.0.8-tem
        ```
        
2. **Install IntelliJ**
    
    * Homebrew:
        
        ```bash
        brew install --cask intellij-idea-ce
        ```
        
    * Or download from JetBrains site / Toolbox.
        
3. **Verify**
    
    ```bash
    java -version
    ```
    

---

## 2\. Install Maven (Windows / Ubuntu / macOS)

Maven builds Java projects and is the most common build tool for Spring Boot (Maven or Gradle both supported).

### Ubuntu

```bash
sudo apt update
sudo apt install maven -y
mvn -v
```

### macOS

```bash
brew install maven
mvn -v
```

### Windows

* Download binary from Apache Maven site, extract, set `MAVEN_HOME`, and add `%MAVEN_HOME%\bin` to `Path`.
    
* Or use package managers: `choco install maven` or `winget`.
    

**Verify**

```bash
mvn -v
```

---

## 3\. Download a Spring Boot project from Spring Initializr

**Option A — Web UI (easy)**

1. Open [https://start.spring.io](https://start.spring.io)
    
2. Choose:
    
    * Project: **Maven Project**
        
    * Language: **Java**
        
    * Spring Boot: choose a stable 3.x version.
        
    * Project Metadata: Group (e.g. `com.example`), Artifact (e.g. `student-api`)
        
    * Packaging: **Jar** (default)
        
    * Java: **17** or later
        
3. Add dependencies, e.g.:
    
    * **Spring Web** (for REST)
        
    * **Spring Data JPA** (for DB)
        
    * **H2 Database** (in-memory for quick testing)
        
    * optional: **Lombok**, **Spring Boot DevTools**, **Validation**
        
4. Click **Generate** → download a ZIP.
    

**Option B — IntelliJ New Project (Spring Initializr integration)**

* File → New → Project → choose **Spring Initializr** → fill details → pick dependencies → Finish. IntelliJ will generate the project and open it.
    

---

## 4\. Create / Import the Spring Boot project in IntelliJ

**From ZIP**:

1. File → Open → select extracted folder containing `pom.xml`.
    
2. IntelliJ will import Maven project and download dependencies.
    

**New Project (built-in)**:

1. File → New → Project → Spring Initializr.
    
2. Fill Group/Artifact, pick Java version and dependencies.
    
3. Finish → project created and ready.
    

IntelliJ has a **Run** green triangle next to the main class. Use it to run the app.

---

## 5\. What is Maven and how it works with Java & Spring Boot? (deep dive)

**Maven** is a build automation and dependency management tool.

* **POM (pom.xml)**: Project Object Model — defines project coordinates (`groupId`, `artifactId`, `version`), dependencies, build plugins, and configuration.
    
* **Lifecycle**: `validate` → `compile` → `test` → `package` → `install` → `deploy`. `mvn package` creates the JAR, `mvn install` installs it in the local Maven repo (`~/.m2/repository`).
    
* **Repositories**: Maven resolves dependencies from remote repositories (Maven Central) into your local repo. Transitive dependency resolution means a dependency’s dependencies are fetched automatically.
    
* **Plugins**: e.g., `spring-boot-maven-plugin` builds executable JAR/WAR and handles repackage steps.
    

**How Spring Boot uses Maven**:

* Spring Boot projects typically use the `spring-boot-starter-parent` in the POM or the Spring Boot dependency management plugin. This parent sets sensible defaults (dependency versions, plugin config).
    
* The `spring-boot-starter-*` dependencies are meta-dependencies — they pull in the libraries you need (e.g., `spring-boot-starter-web` brings Spring MVC + Tomcat).
    
* `spring-boot-maven-plugin` provides `mvn spring-boot:run` and the mechanism to create an **executable jar** with the embedded server.
    

**Minimal** `pom.xml` snippet (illustrative)

```xml
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>3.1.0</version> <!-- example -->
</parent>

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>
  <dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>
```

---

## 6\. Structure of a Spring Boot application (what's inside)

Typical file/directory layout:

```java
student-api/
 ├─ pom.xml
 └─ src/
    ├─ main/
    │  ├─ java/
    │  │   └─ com/example/studentapi/
    │  │       ├─ StudentApiApplication.java   <-- main class
    │  │       ├─ controller/
    │  │       ├─ service/
    │  │       └─ repository/
    │  └─ resources/
    │      ├─ application.properties
    │      ├─ static/
    │      └─ templates/
    └─ test/
       └─ java/
```

Important files:

* `pom.xml`: build & deps.
    
* `src/main/java/...`[`Application.java`](http://Application.java): `main()` bootstraps Spring.
    
* [`application.properties`](http://application.properties) or `application.yml`: runtime config (datasource, server port, logging).
    
* `src/main/resources/static` and `templates`: for web assets / server-side templates.
    
* `src/test/java`: tests.
    

**Note**: Place the `main` application class in a **root package** so component scanning picks up controllers/services in subpackages. For example, `com.example.studentapi.StudentApiApplication` will `@ComponentScan` under `com.example.studentapi.*`.

---

## 7\. `@SpringBootApplication` — internal working (IOC container & dependency injection)

`@SpringBootApplication` is a meta-annotation that expands to:

```java
@Configuration
@EnableAutoConfiguration
@ComponentScan
```

**What that means:**

* `@Configuration` — marks the class as a source of bean definitions.
    
* `@EnableAutoConfiguration` — asks Spring Boot to automatically configure beans based on the classpath (e.g., if Spring MVC is on the classpath, it configures a `DispatcherServlet`). Spring Boot provides many auto-configuration classes; it tries to configure what you need.
    
* `@ComponentScan` — tells Spring to scan the package where the main class resides and its subpackages for Spring components: `@Controller`, `@Service`, `@Repository`, `@Component`, etc.
    

[`SpringApplication.run`](http://SpringApplication.run)`()`:

* Creates an **ApplicationContext** (the IOC container).
    
* Scans components and registers beans.
    
* Applies auto-configurations based on `@Conditional` rules and available classes.
    
* Starts the embedded servlet container (for web apps).
    
* Calls lifecycle callbacks (e.g., `@PostConstruct`).
    

**IOC container & Dependency Injection (DI)**:

* The ApplicationContext holds bean definitions and manages lifecycle (creation, dependency injection, destruction).
    
* **Injection styles**:
    
    * **Constructor injection** (recommended):
        
        ```java
        @Service
        public class StudentService {
          private final StudentRepository repo;
          public StudentService(StudentRepository repo) {
            this.repo = repo;
          }
        }
        ```
        
    * **Field injection** (not recommended):
        
        ```java
        @Autowired
        private StudentRepository repo;
        ```
        
    * **Setter injection**: setter methods annotated with `@Autowired`.
        
* **Bean Scopes**:
    
    * `singleton` (default): one instance per ApplicationContext.
        
    * `prototype`: new instance each request.
        
    * others exist for web contexts (`request`, `session`).
        

**Important**: Prefer constructor injection — it makes code easier to test and avoids nulls.

---

## 8\. Create a REST API using Spring Boot — CRUD example (step-by-step)

We’ll build a simple **Student** CRUD API with H2 (in-memory) and Spring Data JPA.

### 1) Project setup

Create project with dependencies:

* `spring-boot-starter-web`
    
* `spring-boot-starter-data-jpa`
    
* `com.h2database:h2`
    
* (optional) `spring-boot-devtools`, `lombok`
    

Example `pom.xml` (core parts only):

```xml
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>3.1.0</version>
</parent>

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>
  <dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>
```

### 2) [application.properties](http://application.properties) (simple)

`src/main/resources/`[`application.properties`](http://application.properties)

```java
spring.datasource.url=jdbc:h2:mem:studentsdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
```

* `ddl-auto=update` creates tables automatically (good for dev).
    
* H2 console available at `/h2-console` when app runs.
    

### 3) Main application class

[`StudentApiApplication.java`](http://StudentApiApplication.java)

```java
package com.example.studentapi;

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

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

* `@SpringBootApplication` triggers component scanning and auto-configuration.
    

### 4) Entity

[`Student.java`](http://Student.java)

```java
package com.example.studentapi.model;

import jakarta.persistence.*;

@Entity
@Table(name = "students")
public class Student {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @Column(nullable = false)
  private String name;

  private String address;
  private String phone;

  // Constructors
  public Student() {}
  public Student(String name, String address, String phone) {
    this.name = name;
    this.address = address;
    this.phone = phone;
  }

  // Getters and setters...
  public Long getId() { return id; }
  public void setId(Long id) { this.id = id; }
  public String getName() { return name; }
  public void setName(String name) { this.name = name; }
  public String getAddress() { return address; }
  public void setAddress(String address) { this.address = address; }
  public String getPhone() { return phone; }
  public void setPhone(String phone) { this.phone = phone; }
}
```

> Note: I used `jakarta.persistence.*` as modern Spring Boot uses Jakarta packages.

### 5) Repository

[`StudentRepository.java`](http://StudentRepository.java)

```java
package com.example.studentapi.repository;

import com.example.studentapi.model.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
  // Spring Data JPA provides CRUD methods automatically
}
```

### 6) Service (optional but good practice)

[`StudentService.java`](http://StudentService.java)

```java
package com.example.studentapi.service;

import com.example.studentapi.model.Student;
import com.example.studentapi.repository.StudentRepository;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class StudentService {
  private final StudentRepository repo;
  public StudentService(StudentRepository repo) { this.repo = repo; }

  public Student create(Student s) { return repo.save(s); }
  public List<Student> findAll() { return repo.findAll(); }
  public Optional<Student> findById(Long id) { return repo.findById(id); }
  public Student update(Long id, Student s) {
    s.setId(id);
    return repo.save(s);
  }
  public void delete(Long id) { repo.deleteById(id); }
}
```

### 7) Controller (REST endpoints)

[`StudentController.java`](http://StudentController.java)

```java
package com.example.studentapi.controller;

import com.example.studentapi.model.Student;
import com.example.studentapi.service.StudentService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.util.List;

@RestController
@RequestMapping("/api/students")
public class StudentController {
  private final StudentService service;
  public StudentController(StudentService service) { this.service = service; }

  @PostMapping
  public ResponseEntity<Student> create(@RequestBody Student s) {
    Student created = service.create(s);
    return ResponseEntity.created(URI.create("/api/students/" + created.getId())).body(created);
  }

  @GetMapping
  public List<Student> all() { return service.findAll(); }

  @GetMapping("/{id}")
  public ResponseEntity<Student> getById(@PathVariable Long id) {
    return service.findById(id)
      .map(ResponseEntity::ok)
      .orElse(ResponseEntity.notFound().build());
  }

  @PutMapping("/{id}")
  public ResponseEntity<Student> update(@PathVariable Long id, @RequestBody Student s) {
    // simple approach: set id and save
    Student updated = service.update(id, s);
    return ResponseEntity.ok(updated);
  }

  @DeleteMapping("/{id}")
  public ResponseEntity<Void> delete(@PathVariable Long id) {
    service.delete(id);
    return ResponseEntity.noContent().build();
  }
}
```

### 8) Run the app

From IntelliJ: click the Run icon on `StudentApiApplication`. Or from terminal:

```bash
mvn spring-boot:run
```

Application will start (default [`http://localhost:8080`](http://localhost:8080)).

### 9) Test with `curl` (examples)

* Create:
    

```bash
curl -X POST http://localhost:8080/api/students \
  -H "Content-Type: application/json" \
  -d '{"name":"Aisha","address":"Dhaka","phone":"+8801..."}'
```

* Get all:
    

```bash
curl http://localhost:8080/api/students
```

* Get by id:
    

```bash
curl http://localhost:8080/api/students/1
```

* Update:
    

```bash
curl -X PUT http://localhost:8080/api/students/1 \
  -H "Content-Type: application/json" \
  -d '{"name":"Aisha Updated","address":"Dhaka","phone":"0123"}'
```

* Delete:
    

```bash
curl -X DELETE http://localhost:8080/api/students/1
```

You can also use Postman / Insomnia / HTTPie.

---

## 9\. Explanation: each key file and why it matters (quick line-by-line highlights)

* [`StudentApiApplication.java`](http://StudentApiApplication.java) — launches Spring, triggers auto-configuration and component scanning.
    
* `pom.xml` — defines dependencies and `spring-boot-maven-plugin` so `mvn spring-boot:run` and `mvn package` produce runnable JAR.
    
* [`application.properties`](http://application.properties) — runtime settings (DB URL, logging, port). Changing `spring.jpa.hibernate.ddl-auto` impacts schema generation.
    
* `@Entity` Student — JPA entity mapping. `@Id` + `@GeneratedValue` controls primary key generation.
    
* `StudentRepository` — Spring Data JPA gives you `save()`, `findAll()`, `findById()`, `deleteById()` — no boilerplate SQL.
    
* `StudentService` — encapsulates business logic and interacts with repository (keeps controller thin).
    
* `StudentController` — exposes REST endpoints and maps HTTP verbs to CRUD operations.
    

---

## 10\. Common pitfalls & debugging tips

* **Java version mismatch**: If runtime complains about class file version, ensure `java -version` matches JDK used to compile.
    
* **Port in use**: `server.port=8080` can be changed in [`application.properties`](http://application.properties).
    
* **Dependency issues**: Run `mvn clean package` and check for conflicting versions. Spring Boot parent usually manages versions for you.
    
* **H2 console not accessible**: verify `spring.h2.console.enabled=true` and use correct JDBC URL `jdbc:h2:mem:studentsdb`.
    
* **Lombok problems**: If using Lombok, enable annotation processing in IntelliJ (Preferences → Build, Execution, Deployment → Compiler).
    

---

## Short checklist to run the example right now

1. Java 17+ installed and `java -version` OK.
    
2. Maven installed and `mvn -v` OK.
    
3. Create Spring Boot project from [**start.spring.io**](http://start.spring.io) or IntelliJ with dependencies: **Web, JPA, H2**.
    
4. Paste entity/repository/service/controller code shown above.
    
5. [`application.properties`](http://application.properties) as provided.
    
6. Run `mvn spring-boot:run` and test with `curl`.
    

---

Follow me on : [Github](https://github.com/jps27cse) [Linkedin](https://www.linkedin.com/in/jps27cse/) [Threads](https://www.threads.net/@jps.27) [Youtube Channel](https://www.youtube.com/@jps27)
