Around 어드바이스 메소드를 구현할 때 사용하는 ProceedingJoinPoint 인터페이스는 JoinPoint를 상속받은 클래스이다.
따라서 JoinPoint가 갖고있는 모든 메소드를 지원하며 추가적으로 proceed() 메소드가 더해진 셈이다.
주의할점은 Befor, After Returning, After Throwing, After 어드바이스를 JoinPoint를 매개변수로 사용하고, Around 어드바이스에서만 ProceedingJoinPoint를 매개변수로 사용한다는 점. Around 어드바이스에서만 proceed() 메소드가 필요하기 때문이다.
@Before("cut() && enableDecode()")
public void before(JoinPoint joinPoint) throws UnsupportedEncodingException{
Object[] args = joinPoint.getArgs();
String methodName = joinPoint.getSignature().getName();
for(Object arg : args){
if(arg instanceof User){
User user = User.class.cast(arg);
String base64Email = user.getEmail();
String email = new String(Base64.getDecoder().decode(base64Email), "UTF-8");
user.setEmail(email);
}
}
System.out.println("실행된 메소드명: " + methodName);
}
@AfterReturning(value = "pointcut() && enableDecode()", returning = "returnObj")
public void afterReturn(JoinPoint joinPoint, Object returnObj){
if(returnObj instanceof User){
User user = User.class.cast(returnObj);
String email = user.getEmail();
String base64Email = Base64.getEncoder().encodeToString(email.getBytes());
user.setEmail(base64Email);
}
}
2번째 매개변수로 Object 타입의 returnObj가 선언되어 있는데 바인드변수 이다.
바인드변수는 비즈니스 메소드가 리턴한 결과값을 바인딩할 목적으로 사용하며, 어떤 값이 리턴될지 모르기 때문에 타입은 Object로 선언해주는 것이다.
@AfterReturning 안의 returning값에는 2번째 파라미터명과 일치시킨다.
@AfterThrowing(value = "pointcut() && enableDecode()", throwing = "exceptObj")
public void afterThrowing(JoinPoint joinPoint, Exception exceptObj){
String method = joinPoint.getSignature().getName();
String errMsg = exceptObj.getMessage();
System.out.println("메소드명: " + method);
System.out.println("ErrMsg: " + errMsg);
}
@Around("pointcut() && enableDecode()")
public Object around(ProceedingJoinPoint joinPoint){
String method = joinPoint.getSignature().getName();
StopWatch stopWatch = new StopWatch();
stopWatch.start();
System.out.println("around 시작");
Object obj = joinPoint.proceed();
stopWatch.stop();
System.out.println("around 메소드명: " + method + "수행에 걸린 시간: " + stopWatch.getTotalTimeMillis() + "(ms)초");
return obj;
}