SpringBoot 解决项目统一功能

使用 SpringBoot 解决项目统一功能:高效、优雅、易维护

Spring 框架提供了一系列 非侵入式 的解决方案,如 拦截器(Interceptor)、AOP(Aspect-Oriented Programming)、全局异常处理 等,让我们能够 优雅地 解决这些统一功能问题。

1. 为什么需要统一功能?

在企业级项目中,我们经常遇到以下问题:

  1. 日志记录:每个请求都需要打印日志,如果在 Controller 里手写 System.out.println(),代码会非常冗余。
  2. 异常处理:如果每个方法都 try-catch,代码不仅繁琐,还降低了可读性。
  3. 权限校验:有些 API 需要权限控制,如果每个接口都手动检查权限,维护起来非常麻烦。
  4. 请求参数校验:如果每个 Controller 里都手写 if 语句检查参数合法性,代码可读性会很差。

图片[1]-SpringBoot 解决项目统一功能-我的编程笔记记录

这些功能都是 通用功能,不应该和业务逻辑代码混在一起。因此,我们需要 Spring 提供的机制,来解决这些问题。

2. 解决统一功能的 SpringBoot 方案

图片[2]-SpringBoot 解决项目统一功能-我的编程笔记记录

Spring 提供了 三种主要方式 处理统一功能:

  1. 拦截器(Interceptor):适用于 全局请求拦截,比如日志记录、权限校验等。
  2. AOP(切面编程):适用于 方法级别的拦截,如事务管理、性能监控、权限校验等。
  3. 全局异常处理(Exception Handler):适用于 统一异常管理,避免代码中充斥 try-catch 语句。

我们通过 两个实战案例 详细讲解如何使用这些技术。

3. 实战案例 1:使用拦截器实现统一日志管理

需求

我们希望 记录所有 API 请求的日志,包括 请求时间、请求路径、请求参数、请求耗时 等。

解决方案

Spring 提供了 HandlerInterceptor 接口,我们可以自定义一个拦截器,在 请求开始前、请求结束后 记录日志。

实现步骤

1. 创建日志拦截器

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
public class LogInterceptor implements HandlerInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);

private static final ThreadLocal<Long> startTime = new ThreadLocal<>();

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    startTime.set(System.currentTimeMillis());
    logger.info("请求路径: {},请求参数: {}", request.getRequestURI(), request.getQueryString());
    return true;
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    long duration = System.currentTimeMillis() - startTime.get();
    logger.info("请求结束: {},耗时: {}ms", request.getRequestURI(), duration);
    startTime.remove();
}}

2. 注册拦截器

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private LogInterceptor logInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(logInterceptor).addPathPatterns("/**");
}}

所有请求的日志都会自动记录,业务代码完全解耦!

4. 实战案例 2:使用 AOP 实现统一权限管理

需求

假设我们的系统有 管理员和普通用户 ,我们希望 某些 API 只有管理员能访问

解决方案

使用 Spring AOP ,在方法执行前检查用户角色,如果权限不足,直接返回错误信息。

实现步骤

1. 自定义权限注解

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AdminOnly {
}

2. 创建权限校验切面

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AuthAspect {
    @Before("@annotation(AdminOnly)")
    public void checkAdmin() {
        String currentUserRole = "USER"; // 模拟获取当前用户角色
        if (!"ADMIN".equals(currentUserRole)) {
            throw new RuntimeException("权限不足,只有管理员可以访问!");
        }
    }
}

3. 在 API 上使用注解

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/admin")
public class AdminController {
    @GetMapping("/dashboard")
    @AdminOnly
    public String adminDashboard() {
        return "欢迎来到管理员面板!";
    }
}

权限校验被抽离到 AOP 逻辑,业务代码更清晰、更易维护!

5. 全局异常处理

在项目中,我们希望 所有异常都有统一的返回格式 ,而不是让 try-catch充斥代码。Spring 提供了@ControllerAdvice让我们 统一管理异常

实现代码

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public String handleException(Exception e) {
        return "服务器错误:" + e.getMessage();
    }
}

所有异常都会被统一捕获,避免业务代码中充斥 try-catch!

6. 总结

  1. 拦截器(Interceptor) 适用于 全局请求拦截 ,如日志记录、请求统计、统一参数处理。
  2. AOP(切面编程) 适用于 方法级别的功能增强 ,如权限校验、事务管理、性能监控。
  3. 全局异常处理 可用于 集中管理异常 ,避免 try-catch代码污染业务逻辑。
© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享