Spring @ExceptionHandler 완벽 이해하기
이전 글에서 설명한 실무 예외 처리 패턴의 핵심이:
예외 발생
↓
전파
↓
한 곳에서 처리
↓
응답 반환
이라고 했습니다.
그런데 Spring은 어떻게 특정 예외를 잡아서 HTTP 응답으로 변환할까요?
그 역할을 하는 것이 바로:
@ExceptionHandler
입니다.
실제로 Spring MVC 내부에서는:
Controller
↓
예외 발생
↓
DispatcherServlet
↓
ExceptionResolver
↓
@ExceptionHandler
↓
HTTP 응답 생성
흐름으로 동작합니다.
1. @ExceptionHandler란?
ExceptionHandler 는:
특정 예외 발생 시 실행할 메서드를 지정하는 어노테이션
입니다.
2. 가장 기본 예제
@Controller
public class UserController {
@GetMapping("/users/{id}")
public User findUser(
@PathVariable Long id) {
throw new UserNotFoundException();
}
@ExceptionHandler(
UserNotFoundException.class
)
public ResponseEntity<String> handle() {
return ResponseEntity
.status(404)
.body("회원 없음");
}
}
3. 실행 흐름
사용자 요청
GET /users/1
↓
Controller 실행
↓
throw new UserNotFoundException();
↓
Spring이 catch
↓
@ExceptionHandler(
UserNotFoundException.class
)
실행
↓
404 응답 반환
4. 내부적으로 누가 찾을까?
매우 중요.
실제로는:
DispatcherServlet 이 처리합니다.
5. DispatcherServlet 흐름
HTTP 요청
↓
DispatcherServlet
↓
Controller 호출
↓
예외 발생
↓
ExceptionResolver 조회
↓
@ExceptionHandler 실행
↓
Response 반환
6. ExceptionResolver란?
HandlerExceptionResolver 는:
예외를 HTTP 응답으로 변환하는 Spring 컴포넌트
입니다.
7. Spring 기본 Resolver
대표적으로:
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
존재.
8. 가장 중요한 Resolver
ExceptionHandlerExceptionResolver
이 Resolver가
@ExceptionHandler
를 찾아서 실행합니다.
9. 예외 객체 받을 수 있음
예:
@ExceptionHandler(
UserNotFoundException.class
)
public ResponseEntity<?> handle(
UserNotFoundException e) {
return ResponseEntity
.status(404)
.body(e.getMessage());
}
10. 메시지 사용 가능
예외
throw new UserNotFoundException(
"회원 없음"
);
↓
응답
{
"message":"회원 없음"
}
11. 여러 예외 처리 가능
예:
@ExceptionHandler({
UserNotFoundException.class,
ProductNotFoundException.class
})
12. 상위 예외 처리도 가능
예:
@ExceptionHandler(
BusinessException.class
)
그러면
UserNotFoundException
OrderException
전부 처리 가능.
13. 우선순위
매우 중요.
예:
UserNotFoundException
↓
BusinessException
↓
RuntimeException
Spring은
가장 구체적인 예외
를 먼저 찾음.
14. 예시
@ExceptionHandler(
UserNotFoundException.class
)
있고
@ExceptionHandler(
RuntimeException.class
)
도 있으면
UserNotFoundException
발생 시
첫 번째 실행.
15. ResponseEntity 활용
실무 표준.
@ExceptionHandler(
UserNotFoundException.class
)
public ResponseEntity<?> handle() {
return ResponseEntity
.status(404)
.body("회원 없음");
}
16. ErrorResponse DTO 사용
실무에서는 문자열 거의 안 씀.
예:
public record ErrorResponse(
String code,
String message
) {}
17. 응답
@ExceptionHandler(
UserNotFoundException.class
)
public ResponseEntity<?> handle() {
return ResponseEntity
.status(404)
.body(
new ErrorResponse(
"USER_NOT_FOUND",
"회원 없음"
)
);
}
18. 결과
{
"code":"USER_NOT_FOUND",
"message":"회원 없음"
}
19. @ResponseStatus와 함께 사용 가능
예:
@ResponseStatus(
HttpStatus.NOT_FOUND
)
@ExceptionHandler(
UserNotFoundException.class
)
@ResponseStatus(
HttpStatus.NOT_FOUND
)
public ErrorResponse handle() {
return ...
}
20. Controller 내부에 두는 문제
초기에는 많이 씀.
예:
@Controller
public class UserController {
@ExceptionHandler(...)
}
21. 문제점
Controller마다 중복.
UserController
OrderController
ProductController
전부 작성 필요.
22. 그래서 등장
다음 단계가:
@ControllerAdvice
23. @ExceptionHandler + @ControllerAdvice
실무 표준.
구조
Controller
↓
예외 발생
↓
ControllerAdvice
↓
@ExceptionHandler
↓
응답
24. 예시
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(
UserNotFoundException.class
)
public ResponseEntity<?> handle() {
...
}
}
25. 장점
모든 Controller 공통 처리.
26. 로그도 여기서 남김
실무에서는 보통
log.error(...)
를
@ControllerAdvice
에서 수행.
27. 예시
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handle(
Exception e) {
log.error("시스템 오류", e);
...
}
28. Spring Boot 기본 예외 처리
만약
@ExceptionHandler
없으면?
Spring Boot 기본 응답
{
"timestamp":"...",
"status":500,
"error":"Internal Server Error"
}
반환.
29. 왜 직접 구현할까?
서비스마다
{
"code":"USER_NOT_FOUND",
"message":"..."
}
형태 통일 필요.
30. 실무에서 자주 하는 실수
1)
@ExceptionHandler(Exception.class)
만 사용
↓
모든 예외 구분 불가.
2)
Controller마다 작성
↓
중복 폭발.
3)
로그를 여기저기서 남김
↓
중복 로그.
4)
HTTP 상태 코드 안 맞춤
회원 없음
↓
500 반환
잘못된 설계.
31. 실무 추천 구조
Controller
↓
Service
↓
Repository
예외 발생
↓
Custom Exception
↓
@ControllerAdvice
↓
@ExceptionHandler
↓
ErrorResponse
↓
HTTP 응답
32. 핵심 흐름 요약
예외 발생
↓
DispatcherServlet
↓
ExceptionResolver
↓
@ExceptionHandler 탐색
↓
응답 생성
33. 가장 중요한 핵심 한 줄
@ExceptionHandler는
"예외를 HTTP 응답으로 변환하는 Spring MVC의 공식 예외 처리 메커니즘"이다.
34. 면접 단골 질문
Q. @ExceptionHandler는 누가 호출하나요?
DispatcherServlet
↓
ExceptionResolver
이 호출.
Q. Controller 안에 둘 수 있나요?
가능
하지만 실무는
@ControllerAdvice 사용
Q. 여러 @ExceptionHandler가 있으면?
가장 구체적인 예외 타입 우선
다음 글은 Spring @ControllerAdvice / @RestControllerAdvice 입니다.
여기서 DispatcherServlet → HandlerExceptionResolver → @ExceptionHandler → @ControllerAdvice 전체 그림이 완성되고, 실무 표준 예외 처리 구조를 이해하게 됩니다.
'language > java' 카테고리의 다른 글
| Spring MVC 예외 처리 전체 흐름 완벽 이해하기 (0) | 2026.05.29 |
|---|---|
| Spring @ControllerAdvice / @RestControllerAdvice 완벽 이해하기 (0) | 2026.05.29 |
| Java/Spring 실무 예외 처리 패턴 완벽 이해하기 (0) | 2026.05.29 |
| Java 예외 로그 전략 완벽 이해하기 (0) | 2026.05.29 |
| Java 커스텀 예외(Custom Exception) 설계 완벽 이해하기 (1) | 2026.05.29 |
댓글