본문 바로가기
SpringBoot

spring aop

by ByteBridge 2021. 11. 7.
반응형

AOP DI 추가 

implementation 'org.springframework.boot:spring-boot-starter-aop'

controller

@Slf4j
@RestController
@RequestMapping("/api")
public class RestApiController {

  @GetMapping("/get/{id}")
  public String get(@PathVariable Long id, @RequestParam String name){
    return String.format("%s-%s",id, name);
  }

  @PostMapping("/post")
  public UserDto post(@RequestBody UserDto userDto){
    return userDto;
  }

  @Decode
  @PutMapping("/put")
  public UserDto put(@RequestBody UserDto userDto){
    log.info("put: {}",userDto);
    return userDto;
  }

  @Timer
  @DeleteMapping("/delete")
  public void delete() throws InterruptedException {
    Thread.sleep(2000);
  }
}

 

특정  클래스 메서드 실행 전 후 로깅  AOP 컴포넌트 생성

@Slf4j
@Aspect
@Component
public class ApiParamAop {

  //controller 하위 모든 메서드
  @Pointcut("execution(* com.wooriworld.controller..*.*(..))")
  private void myPointCut() {

  }

  //포인트 컷 의 하위 메서드 실행 전
  @Before("myPointCut()")
  public void before(JoinPoint joinPoint){
    Object[] args = joinPoint.getArgs();
    MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
    Method method = methodSignature.getMethod();
    log.info("method: {}", method.getName());
    for(Object obj : args) {
      log.info("Type: {}, ", obj.getClass().getSimpleName());
      log.info("value: {}, ", obj);
    }
  }

  //리턴 오브젝트 파라미터이름과 일치 해야 한다.
  ////포인트 컷 의 하위 메서드 실행 후
  @AfterReturning(value = "myPointCut()", returning = "returnObj")
  public void afterReturn(JoinPoint joinPoint, Object returnObj) {
    log.info("return obj: {}", returnObj);
  }
  /*
  //해당 메서드가 예외 발생시 실행 
  @AfterThrowing(value = "myPointCut()", returning = "returnObj")
  public void afterReturn(JoinPoint joinPoint, Object returnObj) {
    log.info("return obj: {}", returnObj);
  }
  */

}

어노테이션 기반 타이머 AOP 생성

타이머 어노테이션 생성

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Timer {

}

타이머 AOP 생성

@Slf4j
@Aspect
@Component
public class TimerAop {

  //controller 하위 모든 것
  @Pointcut("execution(* com.wooriworld.controller..*.*(..))")
  private void myPointCut() {

  }

  @Pointcut("@annotation(com.wooriworld.annotation.Timer)")
  private void enableTimer(){

  }

  //두가지 조건을 같이 사용 한다.
  @Around("myPointCut() && enableTimer()")
  public void around(ProceedingJoinPoint joinPoint) throws Throwable {
    StopWatch stopWatch = new StopWatch();
    stopWatch.prettyPrint();
    stopWatch.start();

    Object result = joinPoint.proceed();

    //실행 후
    stopWatch.stop();
    log.info("Total Time: {}", stopWatch.getTotalTimeSeconds());

  }
}

어노테이션 기반 디코딩 AOP

디코딩 어노테이션 생성

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Decode {

}

디코딩 AOP 생성

@Slf4j
@Aspect
@Component
public class DecodeAop {

  //controller 하위 모든 것
  @Pointcut("execution(* com.wooriworld.controller..*.*(..))")
  private void myPointCut() {

  }

  @Pointcut("@annotation(com.wooriworld.annotation.Decode)")
  private void enableDecode(){

  }

  @Before("myPointCut() && enableDecode()")
  public void before(JoinPoint joinPoint){
    Object[] args = joinPoint.getArgs();

    for(Object obj: args) {
      if(obj instanceof UserDto) {
        UserDto user = UserDto.class.cast(obj);
        String email = user.getEmail();
        user.setEmail(new String(Base64.getDecoder().decode(email.getBytes(StandardCharsets.UTF_8))));
      }
    }
  }

  @AfterReturning(value = "myPointCut() && enableDecode()", returning = "returnObj")
  public void afterReturn(JoinPoint joinPoint, Object returnObj){
    if(returnObj instanceof UserDto) {
      UserDto user = UserDto.class.cast(returnObj);
      String email = user.getEmail();
      user.setEmail(new String(Base64.getEncoder().encode(email.getBytes(StandardCharsets.UTF_8))));
    }
  }
}

 

샘플 코드: github

반응형

'SpringBoot' 카테고리의 다른 글

Unit Test - ParameterizedTest  (0) 2022.05.21
Java Conditional Unit Test  (0) 2022.05.21
Spring mvc async rest api  (0) 2021.11.07
Spring mvc async rest api  (0) 2021.11.07
java excell downloader in spring boot  (0) 2021.10.31