반응형

공통기능을 필터링처리 하면 코드를 재활용해서 훨씬 코드를 깔끔하게 쓸 수 있다. 
이 공통기능을 AOP처리할거다. 

AOP기능 구현에 앞서 dependency 를 추가해줘야한다. 

// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop
implementation 'org.springframework.boot:spring-boot-starter-aop:2.4.5'

ValidationAdvice
- 유효성 검사를 공통으로 처리하는 곳
- @Aspect가 있어야 AOP를 처리할 수 있는 핸들러가 된다. 
- api쪽 advice와 그냥 advice를 만든다. 

1.
@Before(): 특정 함수 실행직전에 실행
@After(): 특정 함수 실행 직후에 실행
@Around(): 특정 함수 실행직전부터 직후에 관여

2.
-  ....web.api의 모든 컨트롤러의 모든 메소드의 모든 매개변수 가 실행될때 작동된다.
- proceedingJoinPoint : api의 Controller중에 특정 함수가 실행됐으면  proceedingJoinPoint가
그 함수의 매개변수 뿐만 아니라 내부의 모든 정보에 접근할 수 있다.
- 예를들어 profile함수가 실행되는 순간 그 함수의 모든 정보를  proceedingJoinPoint가 담고 profile함수 실행 이전에 apiAdvice가 먼저 실행된다. 
- 그 이후 return proceedingJoinPoint.proceed(); 가 실행되며 profile함수가 실행된다. 

3. 
proceedingJoinPoint.getArgs() 를 통해 함수의 매개변수에 접근해서 리스트에 담는다. 
만약에 매개변수 중에서 BindingResult라는 타입이 있으면 
-> 해당 arg를 BindingResult형으로 다운 캐스팅
-> 만약 bindingResult에 에러가 있다면 -> 유효성 검사 실행

@Component
@Aspect
public class ValidationAdvice {

    @Around("execution(* com.jghan.instaclone.web.api.*Controller.*(..))")
    public Object apiAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

//        System.out.println("==================web api 컨트롤러===================");

        Object[] args = proceedingJoinPoint.getArgs();
        for(Object arg: args){
            if(arg instanceof BindingResult){
                BindingResult bindingResult = (BindingResult) arg;
                if (bindingResult.hasErrors()) {
                    Map<String, String> errorMap = new HashMap<>();

                    for (FieldError error : bindingResult.getFieldErrors()) {
                        errorMap.put(error.getField(), error.getDefaultMessage());
                    }
                    throw new CustomValidationApiException("유효성 검사 실패함", errorMap);
                }
            }
        }
        return proceedingJoinPoint.proceed(); //prfofile함수가 실행됨
    }

    @Around("execution(* com.jghan.instaclone.web.*Controller.*(..))")
    public Object advice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        Object[] args = proceedingJoinPoint.getArgs();
        for(Object arg: args){
            if(arg instanceof BindingResult){
                BindingResult bindingResult = (BindingResult) arg;

                if (bindingResult.hasErrors()) {
                    Map<String, String> errorMap = new HashMap<>();

                    for (FieldError error : bindingResult.getFieldErrors()) {
                        errorMap.put(error.getField(), error.getDefaultMessage());

                    }
                    throw new CustomValidationException("유효성 검사 실패함", errorMap);
                }

            }
        }

        return proceedingJoinPoint.proceed();
    }
}

 

+ Recent posts