一、前言:SpringBoot 3 是 Java 后端的分水岭
SpringBoot 3 基于 Spring 6,要求 Java 17+,引入了 GraalVM Native Image、虚拟线程(Project Loom)、HTTP Interface 客户端等重大特性。本文从项目搭建到生产部署,完整覆盖 SpringBoot 3 的核心实战。
二、快速搭建项目
2.1 最简 pom.xml
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.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.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
</dependencies>
2.2 application.yml 关键配置
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb?useSSL=false&characterEncoding=utf8
username: ${DB_USER}
password: ${DB_PASS}
hikari:
maximum-pool-size: 20
minimum-idle: 5
jpa:
hibernate:
ddl-auto: validate
show-sql: false # 生产环境关闭
三、RESTful API 设计
3.1 标准 Controller 写法
java
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping
public PageResponse<UserDTO> list(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size) {
return userService.list(PageRequest.of(page, size));
}
@GetMapping("/{id}")
public UserDTO getById(@PathVariable Long id) {
return userService.getById(id);
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public UserDTO create(@Valid @RequestBody CreateUserRequest req) {
return userService.create(req);
}
@PutMapping("/{id}")
public UserDTO update(@PathVariable Long id, @Valid @RequestBody UpdateUserRequest req) {
return userService.update(id, req);
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(@PathVariable Long id) {
userService.delete(id);
}
}
3.2 统一响应体
java
@Data
@Builder
public class ApiResponse<T> {
private int code;
private String message;
private T data;
private long timestamp = System.currentTimeMillis();
public static <T> ApiResponse<T> ok(T data) {
return ApiResponse.<T>builder().code(200).message("success").data(data).build();
}
public static <T> ApiResponse<T> error(int code, String message) {
return ApiResponse.<T>builder().code(code).message(message).build();
}
}
四、虚拟线程(Project Loom)
SpringBoot 3.2 原生支持虚拟线程,I/O 密集型场景吞吐量可提升10倍。
yaml
# application.yml 开启虚拟线程
spring:
threads:
virtual:
enabled: true
java
// 无需任何代码改动,SpringBoot 自动将 @Async 和请求处理线程切换为虚拟线程
@Service
public class UserService {
@Async
public CompletableFuture<UserDTO> fetchAsync(Long id) {
// 这里会跑在虚拟线程上,即使线程阻塞也不会耗尽系统线程
return CompletableFuture.completedFuture(getById(id));
}
}
五、全局异常处理
java
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(NotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ApiResponse<Void> handleNotFound(NotFoundException e) {
return ApiResponse.error(404, e.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiResponse<Map<String, String>> handleValidation(MethodArgumentNotValidException e) {
Map<String, String> errors = new HashMap<>();
e.getBindingResult().getFieldErrors()
.forEach(err -> errors.put(err.getField(), err.getDefaultMessage()));
return ApiResponse.error(400, "参数校验失败");
}
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ApiResponse<Void> handleGeneral(Exception e) {
log.error("Unhandled error", e);
return ApiResponse.error(500, "服务器内部错误");
}
}
六、JWT 鉴权
java
@Component
@RequiredArgsConstructor
public class JwtFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
String header = request.getHeader("Authorization");
if (header != null && header.startsWith("Bearer ")) {
String token = header.substring(7);
if (jwtUtil.isValid(token)) {
var auth = new UsernamePasswordAuthenticationToken(
jwtUtil.getUsername(token), null, jwtUtil.getRoles(token));
SecurityContextHolder.getContext().setAuthentication(auth);
}
}
chain.doFilter(request, response);
}
}
七、生产部署
dockerfile
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY target/*.jar app.jar
RUN addgroup -S app && adduser -S app -G app
USER app
EXPOSE 8080
ENTRYPOINT ["java", \
"-XX:+UseContainerSupport", \
"-XX:MaxRAMPercentage=75", \
"-jar", "app.jar"]
💬 SpringBoot 3 实战关键点已经覆盖,收藏备用!有问题欢迎评论区交流。
💬 觉得有用的话,点个赞+收藏,关注我,持续更新优质技术内容!
标签:springboot | java | 后端 | 实战 | 微服务