* 이 포스팅은 shlee0882.tistory.com/206의 포스팅과 www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte:fdl:aop:aspectj 을 학습한 뒤 추가로 공부한 후 재정리한 글입니다.
* 해당 개념을 완벽하게 이해하지 못해 설명이 다소 미흡할 수 있습니다. 참고만 해주세요.
* 2차 가공 및 재배포를 금지합니다. ( 재배포시 출처를 남겨주세요 )
* 오탈자 및 잘못된 내용은 댓글달아주세요.
[ 이전 글 ] AOP 개념 및 설정 + 예제
1. Advice를 정의하는 태그
* <aop:before>
- 메서드 실행 전에 적용되는 어드바이스를 정의
* <aop:after-returning>
- 메서드가 정상적으로 실행된 후에 적용되는 어드바이스를 정의
* <aop:after-throwing>
- 메서드가 예외를 발생시킬 때 적용되는 어드바이스를 정의
- try-catch 블록에서 catch 블록과 비슷
* <aop:after>
- 메서드가 정상적으로 실행되는지 또는 예외를 발생시키는지 여부에 상관없이 어드바이스를 정의
- try-catch-finally에서 finally 블록과 비슷
* <aop:around>
- 메서드 호출 이전, 이후, 예외발생 등 모든 시점에 적용 가능한 어드바이스를 정의
2. JoinPoint 인터페이스
- JoinPoint는 Spring AOP 혹은 AspectJ에서 AOP가 적용되는 지점을 뜻함
- 해당 지점을 AspectJ에서 JoinPoint라는 인터페이스로 나타냄
* JoinPoint 메소드
- getArgs() : 메소드 아규먼트를 반환
- getThis() : 프록시 객체를 반환
- getTarget() : 대상 객체를 반환
- getSignature() : 어드바이즈 또는 메소드의 설명을 반환
- toString() : 어드바이즈되는 메소드의 설명을 출력
3. Aspect 실행 시점을 지정할 수 있는 어노테이션(@)
* @Aspect
- 이 클래스가 Aspect를 나타내는 클래스라는 것을 명시
* @Around
- Advice가 Target 메소드를 감싸서 Target 메소드 호출 전과 후에 실행되는 Advice
- ProceedingJoinPoint의 proceed()를 수행하는데, proceed()의 리턴 값이 sub 메서드의 리턴 값이다.
- 즉 @Advice 내부에서 결과값을 제어
* @Before- 어드바이스 타겟 메소드가 호출되기 전에 어드바이스 기능을 수행
* @After- 타겟 메소드의 결과에 관계없이(즉 성공, 예외 관계없이) 타겟 메소드가 완료되면 어드바이스 기능을 수행
* @AfterReturning- (정상적 반환 이후) 타겟 메소드가 성공적으로 결과값을 반환 후에 어드바이스 기능을 수행
* @AfterThrowing- (예외 발생 이후) 타겟 메소드가 수행 중 예외를 던지게 되면 어드바이스 기능을 수행
2. 소스코드
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/* Aspect 생성 */
@Aspect
public class AopTEST {
// 타겟 메소드가 실행된 시간을 측정하기 위한 로직을 구현
@Around("execution(* com.test.TEST*.*(..))")
public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
long begin = System.currentTimeMillis();
Object retVal = pjp.proceed();
System.out.println(System.currentTimeMillis() - begin);
return retVal;
}
/* 결합점을 지정하여 Advice가 언제 실행될지를 지정하는데 사용 -> 빈의 메소드 실행점을 지정하는 것
* com.test 패키지 하위의 TEST 시작하는 클래스의 모든 세소드 수행과 일치할 targerMethod라는 이름의 pointcut을 정의*/
@Pointcut("execution(public * com.test.TEST*.*(..))")
public void targetMethod(){
// pointcut annotation 값을 참조하기 위한 dummy method
}
/* advice 정의
* advice는 aspect의 실제 구현체로 포인트컷 표현식과 일치하는 결합점에 삽입되어 동작할 수 있는 코드 */
/* beforeTargetMethod() 메소드는 targetMethod()로 정의된 포인트컷 전에 수행 */
@Before("targetMethod()")
public void beforeTargetMethod(JoinPoint thisJoinPoint){
Class clazz = thisJoinPoint.getTarget().getClass();
String className = thisJoinPoint.getTarget().getClass().getSimpleName();
String methodName = thisJoinPoint.getSignature().getName();
System.out.println("AspectUsingAnnotaion.beforeTargetMethod executed");
System.out.println(className + "." + methodName + "executed.");
}
/* 정상적으로 메소드가 실행될 때 수행
* afterReturningTargetMethod() advice는 targetMethod()로 정의된 포인트컷 후에 수행.
* targetMethod() 포인트컷의 실행 결과는 retVal 변수에 저장되어 전달
*/
@AfterReturning(pointcut = "targetMethod()", returning = "retVal")
public void afterReturningTargetMethod(JoinPoint thisJoinPoint, Object retVal){
System.out.println("AspectUsingAnnotation.afterReturningTargetMethod executed." + " return value is [" + retVal + "]");
}
/* 메소드가 수행 중 예외사항을 반환하고 종료하는 경우 수행
* afterThrowingTargetMethod() advice는 targerMethod()로 정의된 포인트컷에서 예외가 발생한 후에 수행.
* targetMethod() 포인트컷에서 발생된 예외는 exception 변수에 저장되어 전달
* */
@AfterThrowing(pointcut = "targetMethod()", throwing = "exception")
public void afterThrowingTargetMethod(JoinPoint thisJoinPoint, Exception exception) throws Exception{
System.out.println("AspectUsingAnnotation.afterThrowingTargetMethod executed.");
//System.out.println("에러가 발생했습니다.", exception);
//throw new BizException("에러가 발생했습니다.", exception);
}
/* 메소드 수행 수 무조건 수행
* 정상 종료와 예외 발생 경우를 모두 처리해야 하는 경우에 사용
* 리소스 해제와 같은 작업이 해당
* */
@After("targetMethod()")
public void afterTargetMethod(JoinPoint thisJoinPoint) {
System.out.println("AspectUsingAnnotation.afterTargetMethod executed.");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
'programming > Spring & WEB' 카테고리의 다른 글
Spring) Spring MVC 동작 구조 (0) | 2021.10.06 |
---|---|
Spring) Maven, pom.xml 정의 (0) | 2021.10.05 |
Spring) AOP 개념 및 설정 + 예제 (0) | 2021.01.26 |
댓글