Spring Boot异常处理全攻略:自定义异常、全局捕获与日志记录的最佳实践

Ivan23
Ivan23 2026-03-03T22:05:05+08:00
0 0 0

引言

在现代企业级应用开发中,异常处理是确保系统稳定性和用户体验的关键环节。Spring Boot作为Java生态中最流行的微服务框架,其异常处理机制的合理设计对于构建健壮的应用程序至关重要。本文将深入探讨Spring Boot中的异常处理机制,从自定义异常设计到全局异常捕获,再到完善的日志记录策略,为您提供一套完整的异常处理解决方案。

什么是Spring Boot异常处理

Spring Boot异常处理机制是应用程序在运行过程中遇到错误时的响应机制。它允许开发者优雅地处理各种异常情况,提供统一的错误响应格式,记录详细的错误信息,并确保应用程序不会因为未处理的异常而崩溃。

在微服务架构中,异常处理尤为重要,因为服务间的调用可能产生各种类型的异常,需要统一的处理策略来保证服务的稳定性和可维护性。

自定义异常类设计

异常类设计原则

在Spring Boot应用中,合理的异常类设计是异常处理的基础。自定义异常类应该遵循以下原则:

  1. 层次化设计:通过继承关系建立异常层次结构
  2. 语义明确:异常类名称应该清晰表达异常的含义
  3. 可扩展性:为异常类提供足够的扩展空间
  4. 信息完整:异常类应该包含足够的错误信息

基础异常类设计

/**
 * 基础业务异常类
 */
public class BaseException extends RuntimeException {
    private static final long serialVersionUID = 1L;
    
    /**
     * 错误码
     */
    private String code;
    
    /**
     * 错误信息
     */
    private String message;
    
    /**
     * 错误参数
     */
    private Object[] args;
    
    public BaseException() {
        super();
    }
    
    public BaseException(String code, String message) {
        super(message);
        this.code = code;
        this.message = message;
    }
    
    public BaseException(String code, String message, Object... args) {
        super(message);
        this.code = code;
        this.message = message;
        this.args = args;
    }
    
    public BaseException(String code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
        this.message = message;
    }
    
    // getter和setter方法
    public String getCode() {
        return code;
    }
    
    public void setCode(String code) {
        this.code = code;
    }
    
    @Override
    public String getMessage() {
        return message;
    }
    
    public void setMessage(String message) {
        this.message = message;
    }
    
    public Object[] getArgs() {
        return args;
    }
    
    public void setArgs(Object[] args) {
        this.args = args;
    }
}

业务异常类设计

/**
 * 业务异常类
 */
public class BusinessException extends BaseException {
    private static final long serialVersionUID = 1L;
    
    public BusinessException(String code, String message) {
        super(code, message);
    }
    
    public BusinessException(String code, String message, Object... args) {
        super(code, message, args);
    }
    
    public BusinessException(String code, String message, Throwable cause) {
        super(code, message, cause);
    }
}

/**
 * 参数异常类
 */
public class ParameterException extends BaseException {
    private static final long serialVersionUID = 1L;
    
    public ParameterException(String code, String message) {
        super(code, message);
    }
    
    public ParameterException(String code, String message, Object... args) {
        super(code, message, args);
    }
    
    public ParameterException(String code, String message, Throwable cause) {
        super(code, message, cause);
    }
}

/**
 * 权限异常类
 */
public class PermissionException extends BaseException {
    private static final long serialVersionUID = 1L;
    
    public PermissionException(String code, String message) {
        super(code, message);
    }
    
    public PermissionException(String code, String message, Object... args) {
        super(code, message, args);
    }
    
    public PermissionException(String code, String message, Throwable cause) {
        super(code, message, cause);
    }
}

异常枚举类设计

为了更好地管理异常信息,可以使用枚举类来定义异常常量:

/**
 * 异常枚举类
 */
public enum ExceptionEnum {
    // 参数异常
    PARAMETER_ERROR("PARAM_001", "参数错误"),
    PARAMETER_MISSING("PARAM_002", "参数缺失"),
    
    // 业务异常
    BUSINESS_ERROR("BUS_001", "业务处理失败"),
    RECORD_NOT_FOUND("BUS_002", "记录未找到"),
    DUPLICATE_RECORD("BUS_003", "重复记录"),
    
    // 权限异常
    PERMISSION_DENIED("PERM_001", "权限不足"),
    UNAUTHORIZED("PERM_002", "未授权访问"),
    
    // 系统异常
    SYSTEM_ERROR("SYS_001", "系统内部错误"),
    SERVICE_UNAVAILABLE("SYS_002", "服务不可用"),
    DATABASE_ERROR("SYS_003", "数据库操作失败");
    
    private final String code;
    private final String message;
    
    ExceptionEnum(String code, String message) {
        this.code = code;
        this.message = message;
    }
    
    public String getCode() {
        return code;
    }
    
    public String getMessage() {
        return message;
    }
}

@ControllerAdvice全局异常处理

全局异常处理器基础实现

/**
 * 全局异常处理器
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    
    /**
     * 处理业务异常
     */
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) {
        log.warn("业务异常: {}", ex.getMessage(), ex);
        
        ErrorResponse errorResponse = ErrorResponse.builder()
                .code(ex.getCode())
                .message(ex.getMessage())
                .timestamp(System.currentTimeMillis())
                .build();
        
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }
    
    /**
     * 处理参数异常
     */
    @ExceptionHandler(ParameterException.class)
    public ResponseEntity<ErrorResponse> handleParameterException(ParameterException ex) {
        log.warn("参数异常: {}", ex.getMessage(), ex);
        
        ErrorResponse errorResponse = ErrorResponse.builder()
                .code(ex.getCode())
                .message(ex.getMessage())
                .timestamp(System.currentTimeMillis())
                .build();
        
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }
    
    /**
     * 处理权限异常
     */
    @ExceptionHandler(PermissionException.class)
    public ResponseEntity<ErrorResponse> handlePermissionException(PermissionException ex) {
        log.warn("权限异常: {}", ex.getMessage(), ex);
        
        ErrorResponse errorResponse = ErrorResponse.builder()
                .code(ex.getCode())
                .message(ex.getMessage())
                .timestamp(System.currentTimeMillis())
                .build();
        
        return ResponseEntity.status(HttpStatus.FORBIDDEN).body(errorResponse);
    }
    
    /**
     * 处理验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidationException(MethodArgumentNotValidException ex) {
        log.warn("验证异常: {}", ex.getMessage(), ex);
        
        StringBuilder message = new StringBuilder();
        ex.getBindingResult().getFieldErrors().forEach(error -> {
            message.append(error.getField()).append(": ").append(error.getDefaultMessage()).append("; ");
        });
        
        ErrorResponse errorResponse = ErrorResponse.builder()
                .code("VALIDATION_ERROR")
                .message(message.toString())
                .timestamp(System.currentTimeMillis())
                .build();
        
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }
    
    /**
     * 处理所有未捕获的异常
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGenericException(Exception ex) {
        log.error("未处理的异常: {}", ex.getMessage(), ex);
        
        ErrorResponse errorResponse = ErrorResponse.builder()
                .code("SYSTEM_ERROR")
                .message("系统内部错误,请稍后重试")
                .timestamp(System.currentTimeMillis())
                .build();
        
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
    }
}

错误响应对象设计

/**
 * 错误响应对象
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ErrorResponse {
    /**
     * 错误码
     */
    private String code;
    
    /**
     * 错误信息
     */
    private String message;
    
    /**
     * 时间戳
     */
    private Long timestamp;
    
    /**
     * 错误详情
     */
    private String details;
    
    /**
     * 请求ID
     */
    private String requestId;
    
    /**
     * 路径
     */
    private String path;
}

异常处理增强功能

/**
 * 增强版全局异常处理器
 */
@ControllerAdvice
@Slf4j
public class EnhancedGlobalExceptionHandler {
    
    @Value("${app.environment:development}")
    private String environment;
    
    /**
     * 处理业务异常
     */
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex, WebRequest request) {
        log.warn("业务异常 - 请求路径: {}, 异常信息: {}", 
                ((ServletWebRequest) request).getRequest().getRequestURI(), 
                ex.getMessage(), ex);
        
        ErrorResponse errorResponse = buildErrorResponse(ex, request);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }
    
    /**
     * 处理验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidationException(
            MethodArgumentNotValidException ex, WebRequest request) {
        log.warn("验证异常 - 请求路径: {}, 异常信息: {}", 
                ((ServletWebRequest) request).getRequest().getRequestURI(), 
                ex.getMessage(), ex);
        
        ErrorResponse errorResponse = buildValidationErrorResponse(ex, request);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }
    
    /**
     * 处理参数绑定异常
     */
    @ExceptionHandler(BindException.class)
    public ResponseEntity<ErrorResponse> handleBindException(BindException ex, WebRequest request) {
        log.warn("参数绑定异常 - 请求路径: {}, 异常信息: {}", 
                ((ServletWebRequest) request).getRequest().getRequestURI(), 
                ex.getMessage(), ex);
        
        ErrorResponse errorResponse = buildBindErrorResponse(ex, request);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }
    
    /**
     * 构建错误响应对象
     */
    private ErrorResponse buildErrorResponse(BaseException ex, WebRequest request) {
        ServletWebRequest servletWebRequest = (ServletWebRequest) request;
        HttpServletRequest httpRequest = servletWebRequest.getRequest();
        
        ErrorResponse.ErrorResponseBuilder builder = ErrorResponse.builder()
                .code(ex.getCode())
                .message(ex.getMessage())
                .timestamp(System.currentTimeMillis())
                .requestId(UUID.randomUUID().toString())
                .path(httpRequest.getRequestURI());
        
        // 生产环境不暴露详细错误信息
        if ("production".equals(environment)) {
            builder.message("操作失败,请稍后重试");
        }
        
        return builder.build();
    }
    
    /**
     * 构建验证错误响应对象
     */
    private ErrorResponse buildValidationErrorResponse(MethodArgumentNotValidException ex, WebRequest request) {
        ServletWebRequest servletWebRequest = (ServletWebRequest) request;
        HttpServletRequest httpRequest = servletWebRequest.getRequest();
        
        List<String> errors = new ArrayList<>();
        ex.getBindingResult().getFieldErrors().forEach(error -> 
            errors.add(String.format("%s: %s", error.getField(), error.getDefaultMessage()))
        );
        
        ErrorResponse.ErrorResponseBuilder builder = ErrorResponse.builder()
                .code("VALIDATION_ERROR")
                .message("参数验证失败")
                .timestamp(System.currentTimeMillis())
                .requestId(UUID.randomUUID().toString())
                .path(httpRequest.getRequestURI())
                .details(String.join("; ", errors));
        
        if ("production".equals(environment)) {
            builder.message("参数验证失败");
        }
        
        return builder.build();
    }
    
    /**
     * 构建绑定错误响应对象
     */
    private ErrorResponse buildBindErrorResponse(BindException ex, WebRequest request) {
        ServletWebRequest servletWebRequest = (ServletWebRequest) request;
        HttpServletRequest httpRequest = servletWebRequest.getRequest();
        
        List<String> errors = new ArrayList<>();
        ex.getBindingResult().getFieldErrors().forEach(error -> 
            errors.add(String.format("%s: %s", error.getField(), error.getDefaultMessage()))
        );
        
        ErrorResponse.ErrorResponseBuilder builder = ErrorResponse.builder()
                .code("BIND_ERROR")
                .message("参数绑定失败")
                .timestamp(System.currentTimeMillis())
                .requestId(UUID.randomUUID().toString())
                .path(httpRequest.getRequestURI())
                .details(String.join("; ", errors));
        
        if ("production".equals(environment)) {
            builder.message("参数绑定失败");
        }
        
        return builder.build();
    }
}

异常信息格式化与国际化

国际化异常处理

/**
 * 国际化异常处理器
 */
@ControllerAdvice
@Slf4j
public class InternationalizedExceptionHandler {
    
    @Autowired
    private MessageSource messageSource;
    
    /**
     * 处理国际化异常
     */
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ErrorResponse> handleBusinessException(
            BusinessException ex, Locale locale) {
        log.warn("业务异常 - 语言环境: {}, 异常信息: {}", locale, ex.getMessage(), ex);
        
        String message = messageSource.getMessage(ex.getCode(), ex.getArgs(), ex.getMessage(), locale);
        
        ErrorResponse errorResponse = ErrorResponse.builder()
                .code(ex.getCode())
                .message(message)
                .timestamp(System.currentTimeMillis())
                .build();
        
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }
    
    /**
     * 处理验证异常国际化
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidationException(
            MethodArgumentNotValidException ex, Locale locale) {
        log.warn("验证异常 - 语言环境: {}, 异常信息: {}", locale, ex.getMessage(), ex);
        
        StringBuilder message = new StringBuilder();
        ex.getBindingResult().getFieldErrors().forEach(error -> {
            String defaultMessage = messageSource.getMessage(
                error.getCode(), 
                error.getArguments(), 
                error.getDefaultMessage(), 
                locale
            );
            message.append(error.getField()).append(": ").append(defaultMessage).append("; ");
        });
        
        ErrorResponse errorResponse = ErrorResponse.builder()
                .code("VALIDATION_ERROR")
                .message(message.toString())
                .timestamp(System.currentTimeMillis())
                .build();
        
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }
}

异常信息格式化工具

/**
 * 异常信息格式化工具类
 */
@Component
public class ExceptionFormatter {
    
    /**
     * 格式化异常堆栈信息
     */
    public String formatStackTrace(Throwable throwable) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        throwable.printStackTrace(pw);
        return sw.toString();
    }
    
    /**
     * 格式化异常信息为JSON
     */
    public String formatExceptionToJson(Throwable throwable) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> errorMap = new HashMap<>();
            
            errorMap.put("exception", throwable.getClass().getName());
            errorMap.put("message", throwable.getMessage());
            errorMap.put("stackTrace", getStackTraceElements(throwable));
            errorMap.put("timestamp", System.currentTimeMillis());
            
            return objectMapper.writeValueAsString(errorMap);
        } catch (Exception e) {
            log.error("格式化异常为JSON失败", e);
            return "{\"error\": \"格式化异常失败\"}";
        }
    }
    
    /**
     * 获取堆栈元素列表
     */
    private List<String> getStackTraceElements(Throwable throwable) {
        List<String> stackTraceElements = new ArrayList<>();
        StackTraceElement[] elements = throwable.getStackTrace();
        
        for (StackTraceElement element : elements) {
            stackTraceElements.add(element.toString());
        }
        
        return stackTraceElements;
    }
}

完善的日志记录策略

日志记录配置

/**
 * 异常日志记录配置
 */
@Configuration
public class ExceptionLoggingConfig {
    
    @Bean
    @Primary
    public ExceptionLogger exceptionLogger() {
        return new ExceptionLogger();
    }
}

/**
 * 异常日志记录器
 */
@Component
@Slf4j
public class ExceptionLogger {
    
    /**
     * 记录严重异常
     */
    public void logSevereException(String operation, Throwable exception, Map<String, Object> context) {
        log.error("严重异常 - 操作: {}, 异常类型: {}, 异常信息: {}", 
                operation, exception.getClass().getSimpleName(), exception.getMessage(), exception);
        
        // 记录上下文信息
        if (context != null && !context.isEmpty()) {
            log.error("异常上下文信息: {}", context);
        }
    }
    
    /**
     * 记录警告异常
     */
    public void logWarningException(String operation, Throwable exception, Map<String, Object> context) {
        log.warn("警告异常 - 操作: {}, 异常类型: {}, 异常信息: {}", 
                operation, exception.getClass().getSimpleName(), exception.getMessage());
        
        if (context != null && !context.isEmpty()) {
            log.warn("异常上下文信息: {}", context);
        }
    }
    
    /**
     * 记录普通异常
     */
    public void logException(String operation, Throwable exception, Map<String, Object> context) {
        log.info("普通异常 - 操作: {}, 异常类型: {}, 异常信息: {}", 
                operation, exception.getClass().getSimpleName(), exception.getMessage());
        
        if (context != null && !context.isEmpty()) {
            log.info("异常上下文信息: {}", context);
        }
    }
}

结合业务场景的日志记录

/**
 * 业务异常日志记录器
 */
@Component
@Slf4j
public class BusinessExceptionLogger {
    
    @Autowired
    private ExceptionLogger exceptionLogger;
    
    /**
     * 记录业务异常
     */
    public void logBusinessException(String operation, BusinessException ex, Map<String, Object> context) {
        Map<String, Object> logContext = new HashMap<>(context);
        logContext.put("errorCode", ex.getCode());
        logContext.put("errorMessage", ex.getMessage());
        logContext.put("exceptionType", "BusinessException");
        
        exceptionLogger.logSevereException(operation, ex, logContext);
    }
    
    /**
     * 记录参数异常
     */
    public void logParameterException(String operation, ParameterException ex, Map<String, Object> context) {
        Map<String, Object> logContext = new HashMap<>(context);
        logContext.put("errorCode", ex.getCode());
        logContext.put("errorMessage", ex.getMessage());
        logContext.put("exceptionType", "ParameterException");
        
        exceptionLogger.logWarningException(operation, ex, logContext);
    }
    
    /**
     * 记录权限异常
     */
    public void logPermissionException(String operation, PermissionException ex, Map<String, Object> context) {
        Map<String, Object> logContext = new HashMap<>(context);
        logContext.put("errorCode", ex.getCode());
        logContext.put("errorMessage", ex.getMessage());
        logContext.put("exceptionType", "PermissionException");
        
        exceptionLogger.logWarningException(operation, ex, logContext);
    }
}

实际应用示例

服务层异常处理示例

/**
 * 用户服务实现类
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private BusinessExceptionLogger businessExceptionLogger;
    
    @Override
    @Transactional
    public User createUser(CreateUserRequest request) {
        try {
            // 验证参数
            validateCreateUserRequest(request);
            
            // 检查用户是否已存在
            if (userRepository.existsByUsername(request.getUsername())) {
                throw new BusinessException(ExceptionEnum.DUPLICATE_RECORD.getCode(), 
                        "用户名已存在");
            }
            
            if (userRepository.existsByEmail(request.getEmail())) {
                throw new BusinessException(ExceptionEnum.DUPLICATE_RECORD.getCode(), 
                        "邮箱已存在");
            }
            
            // 创建用户
            User user = new User();
            user.setUsername(request.getUsername());
            user.setEmail(request.getEmail());
            user.setPassword(passwordEncoder.encode(request.getPassword()));
            user.setCreateTime(new Date());
            
            User savedUser = userRepository.save(user);
            log.info("成功创建用户: {}", savedUser.getId());
            
            return savedUser;
            
        } catch (BusinessException ex) {
            businessExceptionLogger.logBusinessException("创建用户", ex, 
                    Map.of("username", request.getUsername(), "email", request.getEmail()));
            throw ex;
        } catch (Exception ex) {
            businessExceptionLogger.logException("创建用户", ex, 
                    Map.of("username", request.getUsername(), "email", request.getEmail()));
            throw new BusinessException(ExceptionEnum.SYSTEM_ERROR.getCode(), 
                    "创建用户失败");
        }
    }
    
    private void validateCreateUserRequest(CreateUserRequest request) {
        if (request == null) {
            throw new ParameterException(ExceptionEnum.PARAMETER_ERROR.getCode(), 
                    "用户请求参数不能为空");
        }
        
        if (StringUtils.isEmpty(request.getUsername())) {
            throw new ParameterException(ExceptionEnum.PARAMETER_MISSING.getCode(), 
                    "用户名不能为空");
        }
        
        if (StringUtils.isEmpty(request.getEmail())) {
            throw new ParameterException(ExceptionEnum.PARAMETER_MISSING.getCode(), 
                    "邮箱不能为空");
        }
        
        if (StringUtils.isEmpty(request.getPassword())) {
            throw new ParameterException(ExceptionEnum.PARAMETER_MISSING.getCode(), 
                    "密码不能为空");
        }
    }
}

控制器层异常处理示例

/**
 * 用户控制器
 */
@RestController
@RequestMapping("/api/users")
@Slf4j
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @PostMapping
    public ResponseEntity<User> createUser(@Valid @RequestBody CreateUserRequest request) {
        try {
            User user = userService.createUser(request);
            return ResponseEntity.status(HttpStatus.CREATED).body(user);
        } catch (BusinessException ex) {
            log.warn("创建用户业务异常: {}", ex.getMessage());
            throw ex;
        } catch (Exception ex) {
            log.error("创建用户系统异常: {}", ex.getMessage(), ex);
            throw new BusinessException(ExceptionEnum.SYSTEM_ERROR.getCode(), 
                    "创建用户失败");
        }
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        try {
            User user = userService.getUserById(id);
            return ResponseEntity.ok(user);
        } catch (BusinessException ex) {
            log.warn("获取用户业务异常: {}", ex.getMessage());
            throw ex;
        } catch (Exception ex) {
            log.error("获取用户系统异常: {}", ex.getMessage(), ex);
            throw new BusinessException(ExceptionEnum.SYSTEM_ERROR.getCode(), 
                    "获取用户失败");
        }
    }
    
    @GetMapping("/search")
    public ResponseEntity<List<User>> searchUsers(@RequestParam String keyword) {
        try {
            List<User> users = userService.searchUsers(keyword);
            return ResponseEntity.ok(users);
        } catch (BusinessException ex) {
            log.warn("搜索用户业务异常: {}", ex.getMessage());
            throw ex;
        } catch (Exception ex) {
            log.error("搜索用户系统异常: {}", ex.getMessage(), ex);
            throw new BusinessException(ExceptionEnum.SYSTEM_ERROR.getCode(), 
                    "搜索用户失败");
        }
    }
}

性能优化与最佳实践

异常处理性能优化

/**
 * 性能优化的异常处理器
 */
@ControllerAdvice
@Slf4j
public class OptimizedGlobalExceptionHandler {
    
    // 缓存常用的错误消息
    private final Map<String, String> errorCache = new ConcurrentHashMap<>();
    
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) {
        // 使用缓存减少重复的字符串操作
        String message = errorCache.computeIfAbsent(ex.getCode(), 
            code -> buildErrorMessage(code, ex.getMessage()));
        
        ErrorResponse errorResponse = ErrorResponse.builder()
                .code(ex.getCode())
                .message(message)
                .timestamp(System.currentTimeMillis())
                .build();
        
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }
    
    private String buildErrorMessage(String code, String defaultMessage) {
        // 可以在这里添加消息构建逻辑
        return defaultMessage;
    }
    
    /**
     * 异步日志记录
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGenericException(Exception ex) {
        // 异步记录日志,避免阻塞主线程
        CompletableFuture.runAsync(() -> {
            log.error("未处理的异常: {}", ex.getMessage(), ex);
        });
        
        ErrorResponse errorResponse = ErrorResponse.builder()
                .code("SYSTEM_ERROR")
                .message("系统内部错误,请稍后重试")
                .timestamp(System.currentTimeMillis())
                .build();
        
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
    }
}

异常处理监控与告警

/**
 * 异常监控组件
 */
@Component
@Slf4j
public class ExceptionMonitor {
    
    @Autowired
    private MeterRegistry meterRegistry;
    
    private final Counter exceptionCounter;
    private final Timer exceptionTimer;
    
    public ExceptionMonitor(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        this.exceptionCounter = Counter.builder("exceptions.total")
                .description("总异常数")
                .register(meterRegistry);
        this.exceptionTimer = Timer.builder("exceptions.duration")
                .description("异常处理耗时")
                .register(meterRegistry);
    }
    
    /**
     * 记录异常
     */
    public void recordException(String exceptionType, String operation, long duration) {
        exceptionCounter.increment(Tag.of("type", exceptionType), Tag.of("operation", operation));
        
        exceptionTimer.record(duration, TimeUnit.MILLISECONDS, 
                Tag.of("type", exceptionType), Tag.of("operation", operation));
    }
    
    /**
     * 检查异常频率并触发告警
     */
    public void checkExceptionFrequency(String exceptionType, String operation) {
        // 实现异常频率监控逻辑
        // 可以集成到监控系统中
        log.info("异常频率监控 - 类型: {}, 操作: {}", exceptionType, operation);
    }
}

总结

通过本文的详细介绍,我们了解了Spring Boot异常处理的完整解决方案。从自定义异常类的设计到全局异常处理器的实现,再到完善的日志记录策略,每一个环节都至关重要。

一个健壮的异常处理体系应该具备以下特点:

  1. 层次化设计:通过继承关系建立清晰的异常层次结构
  2. 统一响应格式:提供一致的错误响应格式
  3. 详细日志记录:记录足够的上下文信息用于问题排查
  4. 性能优化:避免异常处理影响系统性能
  5. 监控告警:及时发现和处理异常情况

在实际项目中,建议根据具体的业务需求和系统特点来调整异常处理策略,同时要注重异常处理的可维护性和可扩展性。通过合理的异常处理设计,可以大大提高应用程序的稳定性和用户体验。

相关推荐
广告位招租

相似文章

    评论 (0)

    0/2000