AOP 용어
- Target : 부가기능이 적용될 타
- Advice : 부가기능을 수행하는 로직
- JoinPoint : Advice 가 적용될 수 있는 위치(모든 메서드)를 일컷는다.
- PointCut : Advice가 끼어드는(적용 ) 위치
- Aspect : PointCut + Advice 를 의미 = Advicer
코드 예시)
1. Adivice에 바로 PointCut을 넣은 코드
@Slf4j
@Aspect
public class AspectV1 {
@Around("execution(* hello.aop.order..*(..))")
public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("[log] {}", joinPoint.getSignature());
return joinPoint.proceed();
}
}
2. Advice 와 PointCut 메서드로 분리 (포인트 컷의 재사용성을 높일 수 있다, 중복 사용 가능)
@Pointcut("execution(* hello.aop.order..*(..))")
public void allOrder() {}
@Pointcut("execution(* *..*Service.*(..))")
public void allService() {}
@Around("allOrder()")
public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("[log] {}", joinPoint.getSignature());
return joinPoint.proceed();
}
@Around("allOrder() && allService()")
public Object doTransaction(ProceedingJoinPoint joinPoint) throws Throwable{
try {
log.info("[트랜잭션 시작] {}", joinPoint.getSignature());
Object result = joinPoint.proceed();
log.info("[트랜잭션 커밋] {}", joinPoint.getSignature());
return result;
} catch (Exception e) {
log.info("[트랜잭션 롤백] {}", joinPoint.getSignature());
throw e;
}finally {
log.info("[리소스 릴리즈] {}", joinPoint.getSignature());
}
}
3. 우선 순위 지정 예시
우선 순위를 부여하기 위해서는 @Order 어노테이션을 사용 할 수 있다.
클래스 단위로 적용됨으로 한 클래스에서 사용하려면 이너 클래스를 사용해야 함
@Aspect
@Order(2)
public static class logAspect {
@Around("hello.aop.order.aop.Pointcuts.allOrder()")
public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("[log] {}", joinPoint.getSignature());
return joinPoint.proceed();
}
}
@Aspect
@Order(1)
public static class txAspect {
@Around("hello.aop.order.aop.Pointcuts.allOrderAndService()")
public Object doTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
try {
log.info("[트랜잭션 시작] {}", joinPoint.getSignature());
Object result = joinPoint.proceed();
log.info("[트랜잭션 커밋] {}", joinPoint.getSignature());
return result;
} catch (Exception e) {
log.info("[트랜잭션 롤백] {}", joinPoint.getSignature());
throw e;
} finally {
log.info("[리소스 릴리즈] {}", joinPoint.getSignature());
}
}
}
4. Advice를 적용하는 다양한 어노테이션
- @Around
- target의 메서드가 호출되는 앞 뒤에 추가적인 기능을 넣을 수 있다.
- target의 메서드를 호출(.proceed())를 하지 않으면 예외가 발생한다.
- 메서드를 호출하여 Object로 받기 때문에 결과값을 변경하는 등 행위를 할 수 있다.
- @Before
- 메서드가 실행되기 직전 실행할 부가기능을 정의할 수 있다.
- @Around 와 다르게 메서드를 호출하지 않아도 예외가 일어나지 않는다.
- @AfterReturning
- 메서드가 실행된 후의 결과값이 나온 후 부가기능이 수행되도록 한다.
- 어노테이션 안의 값으로 return 값을 받아올 수 있다.
- return 값도 결과값도 컨트롤 할 수 있다.
- @AfterThrowing
- 메서드가 예외를 던졌을 때 실행하는 부가기능을 정의할 수 있다.
- throwing 으로 받아 쓸 수있다.
- @After
- 가장 마지막 수행 되는 부가기능 로직
@Around("hello.aop.order.aop.Pointcuts.allOrderAndService()")
public Object doTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
try {
//@Before
log.info("[트랜잭션 시작] {}", joinPoint.getSignature());
Object result = joinPoint.proceed();
//@AfterReturning
log.info("[트랜잭션 커밋] {}", joinPoint.getSignature());
return result;
} catch (Exception e) {
//@AfterThrowing
log.info("[트랜잭션 롤백] {}", joinPoint.getSignature());
throw e;
} finally {
//@After
log.info("[리소스 릴리즈] {}", joinPoint.getSignature());
}
}
@Before("hello.aop.order.aop.Pointcuts.allOrderAndService()")
public void doBefore(JoinPoint joinPoint) {
log.info("[before] {}", joinPoint.getSignature());
}
@AfterReturning(value="hello.aop.order.aop.Pointcuts.allOrderAndService()",returning = "result")
public void doAfterReturning(JoinPoint joinPoint, Object result) {
log.info("[return] {}", joinPoint.getSignature(),result);
}
@AfterThrowing(value="hello.aop.order.aop.Pointcuts.allOrderAndService()",throwing = "ex")
public void doThrowing(JoinPoint joinPoint, Exception ex) {
log.info("[ex] {}", joinPoint.getSignature(),ex);
}
@After("hello.aop.order.aop.Pointcuts.allOrderAndService()")
public void doAfter(JoinPoint joinPoint) {
log.info("[after] {}", joinPoint.getSignature());
}
코드 출처
인프런 / 김영한 / 스프링 핵심원리, 고급편
'Spring' 카테고리의 다른 글
스프링 AOP 실제 프로젝트 적용 (0) | 2024.01.18 |
---|---|
프록시의 한계와 해결방안(내부 호출) (0) | 2024.01.13 |
AOP의 정의와 프록시/데코레이션 패턴 (1) | 2024.01.04 |
의존 관계 자동 주입(@Autowired, @ComponentScan) (0) | 2024.01.02 |
스프링 컨테이너와 싱글톤(feat. @Configuration) (0) | 2023.12.28 |