Spring Boot has revolutionized Java development by making it easier to create production-ready applications with minimal configuration. This comprehensive tutorial will take you from zero to building your first Spring Boot application with REST APIs, database integration, and best practices.
๐ค What is Spring Boot?
Spring Boot is an extension of the Spring Framework that eliminates the boilerplate configuration required for setting up a Spring application. It provides:
- Auto-configuration: Automatically configures Spring application based on dependencies
- Standalone: Creates standalone Spring applications that run directly
- Production-ready: Includes built-in features like health checks, metrics, and externalized configuration
- No code generation: No XML configuration required
๐ก Why Choose Spring Boot?
Spring Boot reduces development time by 50-70% and is used by over 70% of Java developers worldwide. It's the de facto standard for building microservices and enterprise applications.
โ๏ธ Environment Setup
Before we start, make sure you have the following installed:
Prerequisites:
- Java JDK 11 or higher (OpenJDK or Oracle JDK)
- IDE: IntelliJ IDEA, Eclipse, or VS Code
- Build Tool: Maven or Gradle
- Database: MySQL, PostgreSQL, or H2 (for testing)
Creating Your First Project:
The easiest way to start is using Spring Initializr:
- Visit start.spring.io
- Choose Maven/Gradle and Java
- Enter Group:
com.example
- Enter Artifact:
spring-boot-tutorial
- Add dependencies: Spring Web, Spring Boot DevTools
- Click "Generate" and download the project
๐ Your First Spring Boot Application
Let's create a simple "Hello World" application to understand the basics:
// src/main/java/com/example/springboottutorial/SpringBootTutorialApplication.java
package com.example.springboottutorial;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootTutorialApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootTutorialApplication.class, args);
}
}
Now, let's create a simple controller:
// src/main/java/com/example/springboottutorial/controller/HelloController.java
package com.example.springboottutorial.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "Hello, World! Welcome to Spring Boot!";
}
@GetMapping("/")
public String home() {
return "Spring Boot Tutorial - Your application is running!";
}
}
Run the application: Execute mvn spring-boot:run
in your terminal, then visit http://localhost:8080
๐๏ธ Spring Boot Architecture
Understanding Spring Boot's architecture is crucial for building scalable applications:
1
@SpringBootApplication
Combines @Configuration, @EnableAutoConfiguration, and @ComponentScan
2
Auto-Configuration
Automatically configures beans based on classpath dependencies
3
Embedded Server
Tomcat, Jetty, or Undertow embedded for standalone deployment
๐ Building REST APIs
Let's create a complete REST API for managing users:
// User Entity
package com.example.springboottutorial.entity;
public class User {
private Long id;
private String name;
private String email;
private int age;
// Constructors
public User() {}
public User(Long id, String name, String email, int age) {
this.id = id;
this.name = name;
this.email = email;
this.age = age;
}
// 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 getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
// User Controller with CRUD operations
package com.example.springboottutorial.controller;
import com.example.springboottutorial.entity.User;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
private List<User> users = new ArrayList<>();
private Long nextId = 1L;
// GET all users
@GetMapping
public List<User> getAllUsers() {
return users;
}
// GET user by ID
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = users.stream()
.filter(u -> u.getId().equals(id))
.findFirst()
.orElse(null);
return user != null ? ResponseEntity.ok(user) : ResponseEntity.notFound().build();
}
// POST create new user
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
user.setId(nextId++);
users.add(user);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
// PUT update user
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User updatedUser) {
for (int i = 0; i < users.size(); i++) {
if (users.get(i).getId().equals(id)) {
updatedUser.setId(id);
users.set(i, updatedUser);
return ResponseEntity.ok(updatedUser);
}
}
return ResponseEntity.notFound().build();
}
// DELETE user
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
boolean removed = users.removeIf(u -> u.getId().equals(id));
return removed ? ResponseEntity.noContent().build() : ResponseEntity.notFound().build();
}
}
Testing Your REST API:
Use tools like Postman or curl to test your endpoints:
GET http://localhost:8080/api/users
- Get all users
POST http://localhost:8080/api/users
- Create a user
GET http://localhost:8080/api/users/1
- Get user by ID
PUT http://localhost:8080/api/users/1
- Update user
DELETE http://localhost:8080/api/users/1
- Delete user
๐๏ธ Database Integration
Let's integrate a database using Spring Data JPA:
1. Add Dependencies to pom.xml:
<dependencies>
<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>
2. Create JPA Entity:
// Updated User Entity with JPA annotations
package com.example.springboottutorial.entity;
import javax.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false, unique = true)
private String email;
private int age;
// Constructors, getters, and setters remain the same
}
3. Create Repository:
// UserRepository interface
package com.example.springboottutorial.repository;
import com.example.springboottutorial.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
}
4. Update Controller to use Repository:
// Updated UserController with database operations
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@GetMapping
public List<User> getAllUsers() {
return userRepository.findAll();
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
Optional<User> user = userRepository.findById(id);
return user.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public User createUser(@RequestBody User user) {
return userRepository.save(user);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User userDetails) {
return userRepository.findById(id)
.map(user -> {
user.setName(userDetails.getName());
user.setEmail(userDetails.getEmail());
user.setAge(userDetails.getAge());
return ResponseEntity.ok(userRepository.save(user));
})
.orElse(ResponseEntity.notFound().build());
}
@DeleteMapping("/{id}")
public ResponseEntity<?> deleteUser(@PathVariable Long id) {
return userRepository.findById(id)
.map(user -> {
userRepository.delete(user);
return ResponseEntity.ok().build();
})
.orElse(ResponseEntity.notFound().build());
}
}
๐งช Testing Your Application
Testing is crucial for maintaining code quality. Let's write unit tests:
// UserControllerTest
package com.example.springboottutorial.controller;
import com.example.springboottutorial.entity.User;
import com.example.springboottutorial.repository.UserRepository;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Arrays;
import java.util.Optional;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(UserController.class)
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserRepository userRepository;
@Autowired
private ObjectMapper objectMapper;
@Test
public void testGetAllUsers() throws Exception {
User user1 = new User(1L, "John Doe", "john@example.com", 25);
User user2 = new User(2L, "Jane Smith", "jane@example.com", 30);
when(userRepository.findAll()).thenReturn(Arrays.asList(user1, user2));
mockMvc.perform(get("/api/users"))
.andExpect(status().isOk())
.andExpected(jsonPath("$").isArray())
.andExpect(jsonPath("$[0].name").value("John Doe"))
.andExpect(jsonPath("$[1].name").value("Jane Smith"));
}
@Test
public void testCreateUser() throws Exception {
User user = new User(null, "Test User", "test@example.com", 28);
User savedUser = new User(1L, "Test User", "test@example.com", 28);
when(userRepository.save(any(User.class))).thenReturn(savedUser);
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(user)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(1))
.andExpect(jsonPath("$.name").value("Test User"));
}
}
๐ Deployment Strategies
Spring Boot applications can be deployed in multiple ways:
1. Building JAR File:
# Build executable JAR
mvn clean package
# Run the JAR file
java -jar target/spring-boot-tutorial-0.0.1-SNAPSHOT.jar
2. Docker Deployment:
# Dockerfile
FROM openjdk:11-jre-slim
COPY target/spring-boot-tutorial-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
# Build and run Docker container
docker build -t spring-boot-tutorial .
docker run -p 8080:8080 spring-boot-tutorial
โ
Best Practices
Follow these best practices for production-ready Spring Boot applications:
1. Configuration Management:
- Use
application.properties
or application.yml
- Separate configurations for different environments
- Use
@ConfigurationProperties
for complex configurations
# application.yml
server:
port: 8080
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: update
show-sql: true
logging:
level:
com.example.springboottutorial: DEBUG
2. Error Handling:
// Global Exception Handler
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<String> handleResourceNotFound(ResourceNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGenericException(Exception ex) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("An error occurred: " + ex.getMessage());
}
}
3. Security:
- Use Spring Security for authentication and authorization
- Validate input data
- Use HTTPS in production
- Implement proper logging
๐ Congratulations! You've learned the fundamentals of Spring Boot development. From here, explore advanced topics like microservices, Spring Cloud, and reactive programming.
Next Steps:
- Build more complex projects
- Learn Spring Security
- Explore Spring Cloud for microservices
- Practice with real-world scenarios
๐ฏ Ready to Master Spring Boot?
Join our comprehensive Java Full Stack Development course and master Spring Boot along with frontend technologies, databases, and deployment strategies.
Enroll in Java Full Stack Course
About Visible Campus
Visible Campus is a leading technology training institute specializing in Java, Python, MERN Stack, and emerging technologies. We provide industry-oriented training with 100% placement assistance.
Get in Touch