코딩하는 문과생
[Spring Boot] Spring AOP, 예외 처리 본문
프로젝트 투입 전 약간의 시간이 있어, 스프링을 전체적으로 정리중에 있다.
그중 스프링 검증과 예외처리에 대해 한번의 정리가 필요한 것 같아 그 내용을 정리해보려고 한다.
원론적인 이야기는 배제하고, 실무적으로 필요한 것만 정리한 내용이다.
[Spring AOP]
Spring은 공통 관심사와 비즈니스 로직을 분리할 수 있도록 AOP기능을 제공한다.
즉, 비즈니스 로직에 모든 것을 담으려하지 않고, 예외처리나 로깅 등은 공통 관심사로 뽑아내어 로직을 만들어 핵심 비즈니스 변경 시 영향도를 최대한 줄이고자 한다.
[포인트 컷과 어드바이스]

조인 포인트(Join point) | Advice가 적용될 수 있는 위치. AOP를 적용할 수 있는 모든 지점. 스프링 AOP는 프록시 방식을 사용하기 때문에 조인 포인트는 항상 메서드 실행지점으로 제한된다. |
포인트컷(Pointcut) | 조인 포인트 중에서 Advice가 적용될 위치를 선별 주로 AspectJ 표현식을 사용해서 지정 |
어드바이스(Advice) | 부가기능 조인 포인트에서 취해지는 조치사항 |
즉 포인트 컷은 위치를 선별, 어드바이스는 부가기능이라 생각하면 된다.
포인트컷과 어드바이스를 직접 자바로 구현하는 방법이 있긴 하지만, 스프링 부트에서는 위 과정을 어노테이션 등으로 쉽게 처리하는 방법을 제공해준다.
[실무적인 예외처리 기법]
예전의 스프링은 예외처리에 대해 일일이 구현을 해야했다면, Spring AOP와 Spring Boot 자동환경설정 등으로 간략히 예외처리를 구성할 수 있다.
전제)
Rest API 서버에서 예외발생 시 일관된 예외 리턴
방법 CASE)
1. ControllerAdvice + 자바 정의 예외
2. ControllerAdvice + 사용자 정의 예외
3. ResponseEntityExceptionHandler 클래스의 메서드를 오버라이드하여 정의하는 예외

. CustomizedResponseEntityExceptionHandler.java
package kr.co.sijune.myrestfulservice.exception;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import java.util.Date;
@ControllerAdvice
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
/* CASE 1 : ControllerAdvice + 자바 정의 예외 */
@ExceptionHandler(Exception.class)
public final ResponseEntity<Object> handleAllException(Exception ex, WebRequest request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
/* CASE 2 : ControllerAdvice + 사용자 정의 예외 */
@ExceptionHandler(UserNotFoundException.class)
public final ResponseEntity<Object> handleUserNotFoundException(Exception ex, WebRequest request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(exceptionResponse, HttpStatus.NOT_FOUND);
}
/* CASE 3 : ResponseEntityExceptionHandler 클래스의 메서드를 오버라이드하여 정의하는 예외 */
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(), ex.getMessage(), ex.getBindingResult().toString());
return new ResponseEntity<>(exceptionResponse, HttpStatus.BAD_REQUEST);
}
}
. ExceptionResponse.java
package kr.co.sijune.myrestfulservice.exception;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExceptionResponse {
private Date timestamp;
private String message;
private String details;
}
. UserNotFoundException.java
package kr.co.sijune.myrestfulservice.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException{
public UserNotFoundException(String message) {
super(message);
}
}

https://backtony.github.io/spring/2021-12-29-spring-aop-2/
Spring - AOP 총정리
Java, JPA, Spring을 주로 다루고 공유합니다.
backtony.github.io
'웹 프로그래밍 > Spring Boot' 카테고리의 다른 글
[Spring Boot] Spring Data JPA (0) | 2021.05.01 |
---|---|
[Spring Boot] CI/CD - CD(지속적 배포)(step3) (0) | 2020.12.13 |
[Spring boot] CI/CD - CI(지속적통합)(step2) (0) | 2020.12.12 |
[Spring boot] 프로젝트 AWS에 올리기(step1) (0) | 2020.12.10 |
[Spring Boot] AWS 아키텍처(+ HotSpot으로 연결 시 여러 이슈들) (0) | 2020.12.06 |