AOP, 유효성 검사

화낼거양's avatar
Nov 21, 2024
AOP, 유효성 검사
 
💡
AOP란? : 관점에 따라 조금씩 달라지는 공통된 행위를 설계하는 기법
 
특징 :
  • 부가로직을 만들고 해당 로직은 공통적이여야하며 핵심 로직에서 분리시킨다.
  • 코드의 응집도를 높이고, 재사용성과 유지보수성을 향상시키는 프로그래밍 기법
 

AOP의 주요 개념

 
  1. Aspect (관점):
      • 애플리케이션의 부가적인 기능을 모듈화한 것입니다. 예를 들어, 로깅, 트랜잭션 관리, 보안 등이 Aspect에 해당합니다.
  1. Advice (조언):
      • 실제로 실행되는 부가 기능의 코드입니다. 언제, 어떻게 적용될지를 정의합니다. 주요 유형은 다음과 같습니다:
        • Before: 대상 메서드 실행 전에 실행됩니다.
        • After: 대상 메서드 실행 후에 실행됩니다.
        • After Returning: 대상 메서드가 정상적으로 실행된 후에 실행됩니다.
        • After Throwing: 대상 메서드가 예외를 던진 후에 실행됩니다.
        • Around: 대상 메서드 실행 전후 또는 대체하여 실행됩니다.
  1. Pointcut (시점):
      • Advice가 적용될 지점을 정의합니다. 특정 메서드나 클래스의 실행 시점을 지정할 수 있습니다.
  1. Join Point (결합 지점):
      • Advice가 실행될 수 있는 구체적인 위치를 나타냅니다. 예를 들어, 메서드 호출, 객체 생성 등이 Join Point입니다.
  1. Weaving (위빙):
      • Aspect와 대상 객체를 연결하여 Advice를 적용하는 과정입니다. 컴파일 시점, 클래스 로딩 시점, 런타임 시점에 위빙이 이루어질 수 있습니다.
 
 
 
 
 
 
 

AOP와 유효성 검사를 이용하기 위한 라이브러리

 
  1. Spring Boot Starter AOP
  1. Spring Boot Starter Validation
 
작성자는 Maven Repository 홈페이지에서 찾은 후 build.gradle에 붙여넣었습니다.
 
예시 :
 
notion image
 
 
프로젝트에 맞는 버전을 선택(3.3.5 버전 사용 중)한 뒤, Gradle을 사용 중이기 때문에
아래 이미지와 같이 Gradle을 선택한 후 내용을 복사.
 
notion image
 
 
 
notion image
 
build.gradle 파일안의 dependencies에 붙여넣고 오른쪽 상단의 코끼리 모양 버튼을 누르면 자동으로 다운 받습니다.
 
 
 
 
 
 

직접 사용해보기

 
Spring Framework에서는 AOP를 쉽게 사용할 수 있습니다. 다음은 간단한 로깅 Aspect 예입니다:
 
@Component @Aspect public class MyValidationAspect { // 행위 @Around("@annotation(org.springframework.web.bind.annotation.PostMapping)") // 포인트컷 자리 (post매핑한 메서드) public Object validationCheck(ProceedingJoinPoint jp) throws Throwable { Object[] args = jp.getArgs(); for (Object arg : args) { if(arg instanceof Errors){ Errors errors = (Errors) arg; if(errors.hasErrors()) { String errMsg = errors.getFieldErrors().get(0).getField() +" : "+ errors.getFieldErrors().get(0).getDefaultMessage(); throw new Exception400(errMsg); } } } System.out.println("직전"); // 여기까지 메서드가 실행되기 전 Object ob = jp.proceed(); // 메서드 진행 // 메서드 진행이 끝난 후 System.out.println("직후"); return ob; } }
 
 
 

클래스 및 어노테이션

 
@Component @Aspect public class MyValidationAspect {
 
  • @Component: 이 클래스가 Spring의 빈(bean)으로 등록되도록 합니다.
  • @Aspect: 이 클래스가 AOP의 Aspect임을 나타냅니다.
 

유효성 검사 메서드

 
@Around("@annotation(org.springframework.web.bind.annotation.PostMapping)") // 포인트컷 자리 (post매핑한 메서드) public Object validationCheck(ProceedingJoinPoint jp) throws Throwable {
 
  • @Around: 이 어노테이션은 포인트컷에서 지정한 메서드 실행 전후에 이 메서드를 실행하도록 합니다.
  • 포인트컷: @annotation(org.springframework.web.bind.annotation.PostMapping)@PostMapping이 붙은 모든 메서드를 대상으로 합니다.
  • ProceedingJoinPoint jp: AOP에서 조인 포인트에 대한 정보를 제공하며, 대상 메서드를 호출할 수 있습니다.
 

유효성 검사 로직

 
Object[] args = jp.getArgs(); for (Object arg : args) { if (arg instanceof Errors) { Errors errors = (Errors) arg; if (errors.hasErrors()) { String errMsg = errors.getFieldErrors().get(0).getField() + " : " + errors.getFieldErrors().get(0).getDefaultMessage(); throw new Exception400(errMsg); } } }
 
  • jp.getArgs(): 대상 메서드의 매개 변수(arguments)들을 가져옵니다.
  • 유효성 검사:
    • 인수 중 Errors 타입의 객체가 있는지 확인합니다.
    • Errors 객체가 포함되어 있다면, 유효성 검사 결과를 확인합니다.
    • 오류가 있는 경우 첫 번째 오류 메시지를 가져와 Exception400 예외를 발생시킵니다.
 

메서드 실행 전후 로그

 
System.out.println("직전"); // 여기까지 메서드가 실행되기 전 Object ob = jp.proceed(); // 메서드 진행 // 메서드 진행이 끝난 후 System.out.println("직후"); return ob; }
 
  • System.out.println("직전"): 대상 메서드 실행 전 로그 메시지를 출력합니다.
  • jp.proceed(): 대상 메서드를 실행합니다. 예외가 발생하지 않았다면, 대상 메서드가 정상적으로 실행됩니다.
  • System.out.println("직후"): 대상 메서드 실행 후 로그 메시지를 출력합니다.
  • 반환 값: 대상 메서드의 반환 값을 반환합니다.
 

전체 설명

  • 이 AOP는 @PostMapping이 붙은 메서드 호출 전후에 유효성 검사를 수행합니다.
  • Errors 객체가 포함된 인수를 확인하여 유효성 검사 결과를 처리하고, 오류가 있는 경우 사용자 정의 예외 Exception400을 발생시킵니다.
  • 대상 메서드 실행 전후에 로그 메시지를 출력하여 디버깅에 도움을 줍니다.
 
 
 
 

AOP, 유효성 검사 Test

 
notion image
 
SaveDTO 객체의 title과 content 유효성 검사를 위해 @NotBlank 어노테이션을 필드위에 추가합니다.
(NotBlank : null과 빈 문자열(””)을 허용하지 않습니다.)
 
notion image
 
유효성 검사를 위해 기존 코드에서 아래의 내용이 추가되었습니다.
  • SaveDTO 객체 앞에 @Valid 어노테이션을 추가.
  • Errors 객체를 매개 변수로 추가하였습니다.
 
이 후 컨트롤러 객체의 Post 매핑 메서드 중 save 메서드로 Test를 진행합니다.
 

게시글 쓰기 test :

 
  • 정상적으로 게시글을 작성하면 save 메서드가 작동하기 전 후로 콘솔에 “직전”, “직후” 문자열이 출력.
  • 에러가 발생하면 alert 창과 유효성 검사에 통과하지 못한 필드값의 메세지를 함께 출력 (400에러 구현 내용)
 
💡
validationCheck 메서드 로직 요약 :
  1. post매핑이 된 메서드를 찾는다.
  1. 찾은 메서드의 매개변수를 들고온 뒤, Errors 객체가 있는지 찾는다.
  1. 만약 Errors 객체가 있다면 hasErrors() 메서드를 통해 에러가 있는지 확인하고, 에러가 있다면 400예외를 던진다. (예외를 던지게 되면 여기서 종료.)
  1. 위 내용에서 걸러지지 않는다면 메서드 실행 전후로 “직전”, “직후” 문자열을 콘솔에 출력한다.
  1. 실행한 메서드의 반환 값을 반환한다.
 
 

 
 
제목과 내용을 모두 입력한 뒤 글 쓰기 버튼을 클릭했을 때 콘솔 창 :
notion image
notion image
 
 

 
 
내용을 입력하지 않고 글 쓰기 버튼을 클릭했을 때 콘솔 창:
notion image
notion image
 
 
작성한 MyValidationAspect 클래스의 메서드 내용이 잘 작동하는 것을 확인할 수 있습니다.
 
Share article

moohyun