🚀 스프링 부트에서의 예외 처리 전략: @ExceptionHandler 와 @ControllerAdvice
스프링 부트에서는 API 개발 시 예외 처리가 매우 중요하다. 이때 주로 사용하는 두 가지 방식이 바로
@ExceptionHandler와 @ControllerAdvice이다.
⸻
📌 1. @ExceptionHandler란?
컨트롤러 안에서 발생한 특정 예외를 직접 처리할 수 있게 해주는 어노테이션이다.
• 특징:
• 해당 컨트롤러 내부에서만 작동 (해당 컨트롤러의 예외만 처리 가능)
• 컨트롤러 코드와 예외 처리 코드가 함께 존재 → 코드가 복잡해질 수 있음
• 주로 하나의 컨트롤러 안에서 예외 처리를 간단히 마무리할 때 사용
• 사용 예시:
@RestController
public class UserController {
@GetMapping("/user/{id}")
public UserDto getUser(@PathVariable Long id) {
if (id < 0) {
throw new IllegalArgumentException("잘못된 사용자 ID입니다.");
}
return new UserDto(id, "User " + id);
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<ErrorResult> handleIllegalArgument(IllegalArgumentException e) {
ErrorResult error = new ErrorResult("BAD_REQUEST", e.getMessage());
return ResponseEntity.badRequest().body(error);
}
}
👉 위 방식은 직관적이지만, 만약 여러 컨트롤러에 같은 예외 처리 로직이 반복된다면 비효율적이다.
⸻
📌 2. @ControllerAdvice란?
@ExceptionHandler를 사용하는 예외 처리 메서드를 별도의 클래스에서 관리할 수 있게 해주는 어노테이션이다. 이를 통해 여러 컨트롤러에서 발생하는 예외 처리를 공통으로 관리할 수 있다.
이 방식은 마치 AOP(관점 지향 프로그래밍)처럼, 여러 컨트롤러에 공통된 예외 처리 로직을 적용할 수 있게 해준다.

• 특징:
• 예외 처리 로직을 한 곳에서 관리 가능 → 코드 중복 제거
• 적용 범위를 패키지, 클래스, 어노테이션 등으로 지정 가능
• 컨트롤러 코드를 깔끔하게 유지 가능
• 유지 보수성이 높아짐
글로벌 예외 처리 예시입니다
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<ErrorResult> handleIllegalArgument(IllegalArgumentException e) {
ErrorResult error = new ErrorResult("BAD_REQUEST", e.getMessage());
return ResponseEntity.badRequest().body(error);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResult> handleException(Exception e) {
ErrorResult error = new ErrorResult("INTERNAL_SERVER_ERROR", "서버 내부 오류가 발생했습니다.");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
• 특정 컨트롤러 또는 패키지에만 적용하고 싶다면 다음과 같이 적용 범위를 지정할 수 있다:
// 특정 패키지에만 적용하는 예시
@RestControllerAdvice("com.example.user.controller")
public class UserExceptionHandler {
// UserController 패키지의 예외만 처리
}
⸻
🔖 두 방식의 핵심 차이점 정리
구분 @ExceptionHandler @ControllerAdvice
적용 범위 선언된 컨트롤러 내부 전역 or 지정된 범위
예외 처리 중복 발생 가능 (각 컨트롤러마다 별도 작성 필요) 중복 제거 (공통화)
유지 보수성 낮음 (중복 코드로 인한 관리 어려움) 높음 (한 곳에서 관리 가능)
사용 권장 상황 컨트롤러별 단순 예외 처리 전역 또는 공통적인 예외 처리
⸻
🔥 결론
• 간단하고 제한된 예외 처리라면 @ExceptionHandler로 빠르게 해결 가능하다.
• 현업에서는 거의 반드시 @ControllerAdvice를 활용하여 전역 예외 처리 구조를 만들어 사용하는 것이 좋다.
• 특히 대규모 프로젝트나 여러 팀원이 협업할 때는 일관된 예외 처리를 위해 @ControllerAdvice를 적극적으로 활용하는 것이 효과적이다.
이 두 가지 어노테이션을 적절히 활용하면 깔끔하고 유지 보수성 좋은 예외 처리 구조를 만들 수 있다.