Annotation사용을 위해 xml 파일 설정
LogAdvice
package com.springbook.biz.common;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;
@Service //bean을 생성
@Aspect //Aspect = Pointcut + Advice
public class LogAdvice {
// 메소드가 아니라 표현식(execution..)에 대한 이름을 설정한 것이다.(id)
@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
public void allPointcut() {
}
@Pointcut("execution(* com.springbook.biz..*Impl.get*(..))")
public void getPointcut() {
}
//모든 메서드 실행 전에 printLog 실행
@Before("allPointcut()")
public void printLog(JoinPoint jp) {
System.out.println("[공통 로그] 비즈니스 로직 수행 전 동작");
}
}
BeforeAdvice
package com.springbook.biz.common;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Service;
@Service
@Aspect // 결합하겠다는 뜻
public class BeforeAdvice {
@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
public void allPointcut() {}
@Before("allPointcut()")
public void beforeLog(JoinPoint jp) {
String method = jp.getSignature().getName();
Object[] args = jp.getArgs();
System.out.println("[사전 처리] " + method +
"() 메서드 ARGS 정보 : " + args[0].toString());
//System.out.println("[사전 처리] 비즈니스 로직 수행 전 동작");
}
}
AfterReturningAdvice
package com.springbook.biz.common;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;
import com.springbook.biz.user.UserVO;
@Service
@Aspect
public class AfterReturningAdvice {
@Pointcut("execution(* com.springbook.biz..*Impl.get*(..))")
public void getPointcut() {}
@AfterReturning(pointcut="getPointcut()", returning="returnObj")
public void afterLog(JoinPoint jp, Object returnObj) {
String method = jp.getSignature().getName();
if(returnObj instanceof UserVO) {
UserVO user = (UserVO)returnObj;
if(user.getRole().equals("Admin")) {
System.out.println(user.getName() + " 로그인(Admin)");
}
}
// 연결된 모든 메서드의 정보를 출력해준다
System.out.println("[사후 처리] " + method +
"() 메서드 리턴값 : " + returnObj.toString());
//System.out.println("[사후 처리] 비즈니스 로직 수행 후 동작");
}
}
AfterThrowingAdvice
package com.springbook.biz.common;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;
@Service
@Aspect
public class AfterThrowingAdvice {
@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
public void allPointcut() {}
@AfterThrowing(pointcut="allPointcut()", throwing="exceptObj")
public void exceptionLog(JoinPoint jp, Exception exceptObj) {
String method = jp.getSignature().getName();
System.out.println("[예외 처리] " + method +
"() 메서드 수행 중 발생된 예외 메시지 : " + exceptObj.getMessage());
//디테일한 예외 종류 처리
if(exceptObj instanceof IllegalArgumentException) {
System.out.println("부적합한 값이 입력되었습니다");
}else if(exceptObj instanceof NumberFormatException) {
System.out.println("숫자 형식의 값이 아닙니다");
//Exception의 순서는 마지막에 와야한다. 모든 예외의 부모클래스이기 때문이다.
}else if(exceptObj instanceof Exception) {
System.out.println("문제가 발생했습니다");
}
}
}
예외 발생을 위한 코드 추가
AfterAdvice
@Service
@Aspect
public class AfterAdvice {
@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
public void allPointcut() {}
@After("allPointcut()")
public void finallyLog() {
System.out.println("[사후 처리] 비즈니스 로직 수행 후 무조건 동작");
}
}
AroundAdvice
@Service
@Aspect
public class AroundAdvice {
@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
public void allPointcut() {}
@Around("allPointcut()")
public Object aroundLog(ProceedingJoinPoint pjp) throws Throwable{
String method = pjp.getSignature().getName();
StopWatch stopWatch = new StopWatch();
stopWatch.start();
Object obj = pjp.proceed();
stopWatch.stop();
System.out.println(method + "() 메서드 수행에 걸린 시간 : " +
stopWatch.getTotalTimeMillis() + "(ms)초");
return obj;
}
}
pointcut을 한군데에 몽땅 몰아넣자
PointcutCommon
package com.springbook.biz.common;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class PointcutCommon {
@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
public void allPointcut() {}
@Pointcut("execution(* com.springbook.biz..*Impl.get*(..))")
public void getPointcut() {}
}
BeforeAdvice
@Service
@Aspect
public class BeforeAdvice {
@Before("PointcutCommon.allPointcut()")
public void beforeLog(JoinPoint jp) {
String method = jp.getSignature().getName();
Object[] args = jp.getArgs();
System.out.println("[사전 처리] " + method +
"() 메서드 ARGS 정보 : " + args[0].toString());
}
}
AfterReturningAdvice
@Service
@Aspect
public class AfterReturningAdvice {
@AfterReturning(pointcut="PointcutCommon.getPointcut()", returning="returnObj")
public void afterLog(JoinPoint jp, Object returnObj) {
String method = jp.getSignature().getName();
if(returnObj instanceof UserVO) {
UserVO user = (UserVO)returnObj;
if(user.getRole().equals("Admin")) {
System.out.println(user.getName() + " 로그인(Admin)");
}
}
// 연결된 모든 메서드의 정보를 출력해준다
System.out.println("[사후 처리] " + method +
"() 메서드 리턴값 : " + returnObj.toString());
//System.out.println("[사후 처리] 비즈니스 로직 수행 후 동작");
}
}