Spring) 유효성검사3 - AOP

TigerFriend·2023년 10월 14일
0

웹 개발

목록 보기
7/7

AOP (Aspect-Oriented Programming)는 관심사를 분리하여 코드 모듈화를 할 수 있도록 스프링 부트에서 지원하는 라이브러리다.

어노테이션을 통해 원하는 위치의 코드가 실행할 때, 부수적으로 수행할 공통기능을 정의할 수 있다.

AOP는 아래 세가지 용어로 설명하고 이를 활용해 수행한다.

  1. Aspect 생성 : 로깅 기능(Advice)를 포함하는 클래스 생성
  2. Advice 생성 : 메서드 실행 전후에 로그를 남기는 코드를 작성합니다. (수행할 메서드 생성)
  3. Pointcut 적용 : Advice가 작동할 메서드를 설정

먼저 아래와 같이 join(회원가입)하는 메서드가 있다.

@PostMapping("/join")
    public String join(@Valid UserRequest.JoinDTO requestDTO, Errors errors){
        System.out.println(requestDTO);

        if (errors.hasErrors()) {
            for (FieldError error : errors.getFieldErrors()) {
                throw new Exception400(error.getDefaultMessage()+" : "+error.getField());
            }
        }

        return "redirect:/loginForm";
    }

이 join메서드는 @Valid 어노테이션을 통해 DTO 필드에 붙어있는 조건을 검사하고(NotNull 등) 검사에 통과하지 못하면 Errors에 저장한다. 이 중 아래 부분은 login에도 유효성검사를 진행하기에 반복되는 코드가 생긴다.

//코드 반복!
if (errors.hasErrors()) {
            for (FieldError error : errors.getFieldErrors()) {
                throw new Exception400(error.getDefaultMessage()+" : "+error.getField());
            }
        }

이를 전담하여 관리할 클래스를 생성한다. 해당 클래스 위에 @Aspect 어노테이션을 작성하여 디스패쳐 서블릿이 예외를 인식할 때 이 클래스로 전달할 수 있도록 한다.

@Aspect
@Component
public class ValidAdvice {


    @Before("@annotation(org.springframework.web.bind.annotation.PostMapping)")
    public void validationAdvice(JoinPoint jp) throws Throwable { //advice
        Object[] args = jp.getArgs(); //jp의 매개변수에 접근 가능 //UserController의 join(Dto,Errors)
        for (Object arg : args) {
            if (arg instanceof Errors) { //해당 매개변수가 Errors면,
                Errors errors = (Errors) arg; //다운 캐스팅

                if (errors.hasErrors()) {
                    for (FieldError error : errors.getFieldErrors()) {
                        throw new Exception400(error.getDefaultMessage()+" : "+error.getField());
                    }
                }
            }
        }
    }
}

또한 @Before어노테이션을 통해 Pointcut을 발동하여 수행되기전에 어노테이션이 적용된 메서드를 실행한다. 내부에서 JointPoint객체로 받아 매개변수에 접근하여 에러 종류에 대한 예외처리를 진행할 수 있다.

controller에서 공통적인 예외처리 코드를 뺄 수 있게 된다.

@RequiredArgsConstructor
@RestController
public class UserController {

    // Valid AOP 발동
    @PostMapping("/valid")
    public String join(@Valid JoinDTO joinDTO, Errors errors){
        System.out.println(joinDTO);
        return "ok";
    }
}
profile
TigerFriends

0개의 댓글