本文将从零开始,详细介绍如何使用Spring Boot快速构建一个完整的Web应用。通过一个用户管理API的实例,带你掌握Spring Boot的核心功能、项目结构和开发流程。
一、为什么选择Spring Boot?
Spring Boot是Java领域最流行的微服务框架之一,它具有以下优势:
-
快速启动:内置Tomcat,无需单独部署
-
简化配置:约定大于配置,大量默认配置
-
独立运行:直接打包为可执行JAR文件
-
生产就绪:提供监控、健康检查等功能
二、开发环境准备
2.1 必需工具
-
JDK 8或更高版本
-
Maven 3.3+ 或 Gradle 4.4+
-
IDE推荐:IntelliJ IDEA或Spring Tools Suite
2.2 快速检查环境
bash
# 检查Java版本 java -version # 检查Maven mvn -v
三、创建第一个Spring Boot项目
3.1 使用Spring Initializr(推荐)
访问 start.spring.io 生成项目:
选择配置:
-
Project: Maven
-
Language: Java
-
Spring Boot: 2.7.x 或 3.x
-
Dependencies: Spring Web, Spring Data JPA, H2 Database
3.2 项目结构说明
text
my-springboot-app/ ├── src/ │ ├── main/ │ │ ├── java/com/example/ │ │ │ ├── controller/ # 控制器层 │ │ │ ├── service/ # 业务层 │ │ │ ├── repository/ # 数据访问层 │ │ │ ├── entity/ # 实体类 │ │ │ └── Application.java # 主启动类 │ │ └── resources/ │ │ ├── application.yml # 配置文件 │ │ └── static/ # 静态资源 │ └── test/ # 测试代码 ├── pom.xml # Maven配置 └── README.md
四、核心代码实现
4.1 主启动类
java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4.2 实体类定义
java
package com.example.demo.entity;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String email;
private Integer age;
@Column(name = "create_time")
private LocalDateTime createTime;
// 构造器、getter/setter、toString省略
// 可使用Lombok的@Data注解简化
}
4.3 数据访问层
java
package com.example.demo.repository;
import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// 自定义查询方法
List<User> findByAgeGreaterThan(Integer age);
User findByUsername(String username);
}
4.4 业务逻辑层
java
package com.example.demo.service;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User createUser(User user) {
user.setCreateTime(LocalDateTime.now());
return userRepository.save(user);
}
public List<User> getAllUsers() {
return userRepository.findAll();
}
public User getUserById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("用户不存在"));
}
public User updateUser(Long id, User userDetails) {
User user = getUserById(id);
user.setUsername(userDetails.getUsername());
user.setEmail(userDetails.getEmail());
user.setAge(userDetails.getAge());
return userRepository.save(user);
}
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
4.5 控制器层(REST API)
java
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "*") // 允许跨域
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
User savedUser = userService.createUser(user);
return new ResponseEntity<>(savedUser, HttpStatus.CREATED);
}
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.getAllUsers();
return ResponseEntity.ok(users);
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userService.getUserById(id);
return ResponseEntity.ok(user);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id,
@RequestBody User userDetails) {
User updatedUser = userService.updateUser(id, userDetails);
return ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return ResponseEntity.noContent().build();
}
}
五、配置文件详解
5.1 application.yml
yaml
server:
port: 8080
servlet:
context-path: /demo
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
h2:
console:
enabled: true
path: /h2-console
jpa:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
format_sql: true
logging:
level:
com.example.demo: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
六、运行与测试
6.1 启动应用
bash
# 方式一:使用Maven mvn spring-boot:run # 方式二:直接运行主类 # 在IDE中运行Application.java
6.2 测试API
bash
# 创建用户
curl -X POST http://localhost:8080/demo/api/users \
-H "Content-Type: application/json" \
-d '{"username":"zhangsan","email":"zhangsan@example.com","age":25}'
# 查询所有用户
curl http://localhost:8080/demo/api/users
# 查询单个用户
curl http://localhost:8080/demo/api/users/1
# 访问H2控制台
# 浏览器打开:http://localhost:8080/demo/h2-console
6.3 单元测试示例
java
package com.example.demo.controller;
import com.example.demo.entity.User;
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.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Test
void testCreateUser() throws Exception {
User user = new User();
user.setUsername("testuser");
user.setEmail("test@example.com");
user.setAge(30);
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(user)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.username").value("testuser"));
}
}
七、生产环境部署
7.1 打包应用
bash
# 打包为可执行JAR mvn clean package -DskipTests # 生成的JAR文件在target目录下
7.2 运行部署
bash
# 直接运行JAR java -jar target/my-springboot-app-1.0.0.jar # 指定配置文件 java -jar target/my-springboot-app-1.0.0.jar \ --spring.profiles.active=prod
7.3 Docker部署
dockerfile
# Dockerfile FROM openjdk:11-jre-slim VOLUME /tmp COPY target/*.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"]
八、常见问题与解决方案
Q1: 端口被占用
text
Error: Web server failed to start. Port 8080 was already in use.
解决方案:
yaml
# application.yml中修改端口 server: port: 8081
Q2: 数据库连接失败
解决方案: 检查数据库配置、驱动版本和网络连接
Q3: 静态资源访问404
解决方案: 将资源放在src/main/resources/static/目录下
九、Spring Boot最佳实践
-
分层清晰:严格按照Controller-Service-Repository分层
-
异常统一处理:使用@ControllerAdvice全局异常处理
-
参数校验:使用@Valid注解进行参数校验
-
日志规范:使用SLF4J记录日志
-
配置文件分离:不同环境使用不同配置文件
-
API文档:集成Swagger/OpenAPI生成接口文档
十、总结
Spring Boot极大地简化了Spring应用的初始搭建和开发过程。通过本文的实例,你应该已经掌握了:
-
Spring Boot项目的创建和配置
-
完整的MVC三层架构实现
-
RESTful API的设计与开发
-
数据库操作和单元测试
-
项目的打包和部署
后续学习建议:
-
深入学习Spring Security实现权限控制
-
学习使用Spring Cloud构建微服务
-
探索Spring Boot的监控和性能优化
-
研究分布式配置中心和服务发现
技术栈推荐:
-
缓存:Redis
-
消息队列:RabbitMQ/Kafka
-
搜索:Elasticsearch
-
监控:Prometheus + Grafana
1587

被折叠的 条评论
为什么被折叠?



