Spring AOP의 핵심기능과 부가기능
AOP는 업무 로직을 포함하는 핵심기능과 핵심기능을 도와주는 부가적인 기능(로깅,보안,트랜젝션)인 부가기능으로 나누어서 볼 수 있는데, 이 관점을 기준으로 각각 모듈화 하겠다는 개념으로 볼 수 있다.
코드상에서 다른 부분에 계속 반복해서 쓰는 코드들을 발견 할 수 있는데 이것을 흩어진 관심사라 부른다.

예시로) 코드1 이 Class A와 Class B 에서 사용중이라면 Aspect X로 모듈화 할 수 있으며 재사용 할 수 있다.
AOP용어정리
| Target | 핵심기능을 담고 있는 모듈. 부가기능을 부여할 대상이 됨. Aspect 를 적용하는 곳 (클래스, 메소드 ...) |
| Advice | 실질적으로 어떤 일을 해야할 지에 대한 것. (실질적인 부가기능을 담은 모듈) |
| Join Point | Advice가 적용될 위치. 타켓 객체가 구현한 인터페이스의 모든 메서드는 조인포인트가됨. ex) 메서드 진입지점, 생성자 호출시점, 필드에서 값을 꺼내올 때 등 |
| Pointcut | Advice를 적용할 타켓의 메서드를 선별하는 정규표현식. JointPoint 의 상세한 스펙을 정의한 것. 포인트컷 표현식은 execution으로 시작하고 메서드의 Signature를 비교하는 방법을 주로 이용함. |
| Aspect | = Advice + PointCut AOP의 기본 모듈. 싱글톤 형태의 객체로 존재. |
| Advisor | = Advice + PointCut Spring AOP에서만 사용되는 특별한 용어 |
| Weaving | 포인트컷에 의해서 결정된 타켓의 조인포인트에 부가기능(어드바이스)를 삽입하는 과정. AOP가 핵심기능(타켓)의 코드에 영향을 주지 않으면서 필요한 부가기능(어드바이스)을 추가할 수 있도록 해주는 핵심적인 처리과정임. |
AOP의 구현방식
1. XML 기반의 POJO클래스를 이용한 AOP구현
부가기능을 제공하는 Advice클래스를 작성한다. XML 설정파일에 <aop:config> 를 이용해서 Aspect를 설정한다.
2. @Aspect어노테이션을 이용한 AOP구현
@Aspect 어노테이션을 이용해서 부가기능을 제공하는 Aspect 클래스를 작성한다. 이 때 Aspect 클래스는 어드바이스를 구현하는 메서드와 포인트컷을 포함한다.
Aspect 란?
Aspect 는 부가기능을 정의한 코드인 Advice와 Advice를 어디에 적용할지 결정하는 포인트컷(PointCut)을 합친 개념이다.
(Advice + Pointcut = Aspect) AOP개념을 적용하면 핵심기능 코드 사이에 침투된 부가기능을 독립적인 Aspect 로 구분해 낼 수 있으며, 구분된 부가기능은 런타임시에 필요한 위치에 동적으로 참여할 수 있게 된다.
@Aspect
@Component
public class LoggingAspect {
@Before(value = "execution(* [프로젝트].exception.handler.GlobalExceptionHandler.*(..)) && args(exception, webRequest)", argNames = "exception,webRequest")
public void logExceptionBeforeMethod(Exception exception, WebRequest webRequest){
코드작성
}
}
@Aspect 어노테이션을 붙여 해당 클래스가 Aspect 클래스 라는 것을 명시하고 @Component 를 붙여 스프링 빈으로 등록한다.
@Before 어노테이션은 Advice타켓 메소드가 호출되기 전에 Advice 가능을 수행함을 의미한다. 추가적으로 execution(* ..)가 의미하는 바는 ~.GlobalExceptionHandler 아래 패키지 경로의 모든 메서드에 이 Aspect 를 적용하겠다는 의미.
Aspect실행 지점을 지정할 수 있는 어노테이션 (Advice)의 종류
| @Before (이전) | 어드바이스 타켓 메소드가 호출되기 전에 어드바이스 기능을 수행. -> JoinPoint 앞에서 실행 <aop:before> |
| @After (이후) | 타켓 메소드의 결과에 관계없이 타켓 메소드가 완료되면 어드바이스 기능을 수행 -> try-catch-finally 에서 finally 블록과 비슷. <aop:after> |
| @AfterReturning (정상적 반환 이후) | 타켓 메소드가 성공적으로 결과값을 반환 후에 어디바이스기능 수행 -> JoinPoint 메서드 호출이 정상적으로 종료된 뒤에 실행 <aop:after-returning> |
| @AfterThrowing (예외 발생 이후) | 타켓 매소드가 수행 중 예외를 던지게 되면 어드바이스 기능을 수행 -> 예외가 던져질 때 실행 -> try-catch 블록에서 catch블록과 비슷함. <aop:after-throwing> |
| @Around (메소드 실행 전후) | 어디바이스 타켓 메소드를 감싸서 타켓 메소드 호출전과 후에 어드바이스 기능을 수행 -> JoinPoint 앞과 뒤에서 실행 <aop:around> |
JointPoint 는 Spring AOP 혹은 AspectJ에서 AOP가 적용되는 지점을 의미한다. 해당 지점을 AspectJ에서 JointPoint 라는 인터페이스로 나타낸다.
@Around("@annotation(com.example.testing.poly.MethodAop)")
public Object aspectParameter(final ProceedingJoinPoint joinPoint) throws Throwable {
log.error("[aspectParameter] name: {}", joinPoint.getArgs()[0]);
return joinPoint.proceed();
}
출처: https://mangkyu.tistory.com/231 [MangKyu's Diary:티스토리]
예시로 jointPoint.getArgs() 를 통해 파라미터를 직접 조회 할 수 있다.
포인트컷 지시자의 종류
포인트컷 표현식은 execution 같은 포인트컷 지시자로 시작한다.
| execution | 메서드 실행 조인포인트를 매칭함. 스프링 AOP에서 가장 많이 사용하며, 기능도 복잡 |
| within / @within | 특정 타입내의 조인포인트를 매칭. |
| args / @args | 인자가 주어진 타입의 인스턴스인 조인포인트 |
| this | 스프링 빈 객체(Spring AOP 프록시) 를 대상으로 하는 조인 포인트 |
| target / @target | Target 객체(Spring AOP프록시가 가리키는 실제 대상)를 대상으로 하는 조인포인트 |
| @annotation | 메서드가 주어진 어노테이션을 가지고 있는 조인포인트를 매칭 |
| bean | 스프링 전용 포인트컷 지시자로 빈의 이름으로 포인트컷을 지정 |
포인트컷 표현식
@Pointcut("execution(public * *(..))")
private void anyPulbicOperation(){}
// 모든 공개 메서드 실행
execution(public * *(..))
// set 다음 이름으로 시작하는 모든 메서드 실행
execution(* set*(..))
// AccountService 인터페이스에 의해 정의된 모든 메서드의 실행
execution(* com.xyz.service.AccountService.*(..))
// service 패키지에 정의된 메서드 실행
execution(* com.xyz.service.*.*(..))
// 서비스 패키지 또는 해당 하위 패키지 중 하나에 정의된 메서드 실행
execution(* com.xyz.service..*.*(..))
// 서비스 패키지 내의 모든 조인 포인트
within(com.xyz.service.*)
// 서비스 패키지 또는 하위 패키지 중 하나 내의 모든 조인 포인트
within(com.xyz.service..*)
// AccountService 프록시가 인터페이스를 구현하는 모든 조인 포인트
this(com.xyz.service.AccountService)
// AccountService 대상 객체가 인터페이스를 구현하는 모든 조인 포인트
target(com.xyz.service.AccountService)
// 단일 매개변수를 사용하고 런타임에 전달된 인수가 Serializable과 같은 모든 조인 포인트
args(java.io.Serializable)
// 대상 객체에 @Transactional 애너테이션이 있는 모든 조인 포인트
@target(org.springframework.transaction.annotation.Transactional)
// 실행 메서드에 @Transactional 애너테이션이 있는 조인 포인트
@annotation(org.springframework.transaction.annotation.Transactional)
// 단일 매개 변수를 사용하고 전달된 인수의 런타임 유형이 @Classified 애너테이션을 갖는 조인 포인트
@args(com.xyz.security.Classified)
// tradeService 라는 이름을 가진 스프링 빈의 모든 조인 포인트
bean(tradeService)
// 와일드 표현식 *Service 라는 이름을 가진 스프링 빈의 모든 조인 포인트
bean(*Service)
출처: https://ittrue.tistory.com/233 [IT is True:티스토리]
@Pointcut("execution(* ~~.*(..)) && args(~~)") 과 같이 조합하여 사용도 가능하다.
@RestControllerAdvice
@RequiredArgsConstructor
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(MomApiException.class)
public ResponseEntity<ExceptionResponse> handleMomApiException(MomApiException e, WebRequest request) {
..코드작성..
}
}
@Aspect
@Component
public class LoggingAspect {
@Before(value = "execution(* [프로젝트].exception.handler.GlobalExceptionHandler.*(..)) && args(exception, webRequest)", argNames = "exception,webRequest")
public void logExceptionBeforeMethod(Exception exception, WebRequest webRequest){
..코드작성..
}
}
GlobalExceptionHandler 클래스의 하위 메소드를 실행 시키면서 메소드의 exeption과 webrequest 파라미터의 전달받은 값을 추적하고 싶다는 의미로 value = "execution( ... ) && args( ... )" 의 포인트컷 표현식을 사용하였다.
execution(* [프로젝트명].exception.handler.GlobalExceptionHandler.*(..))
-> 하위 모든 메소드에 Aspect 를 적용.
args(exception, webrequest)
-> 메소드의 파라미터 값을 주입받음. ( 해당 타입이 순서대로 매칭되어야 AOP가 적용됨 )
@Before
-> GlobalExceptionHandler 클래스 하위 메소드가 실행 되기 전에 실행.
※ 참고한 블로그
https://shlee0882.tistory.com/206
Spring AOP, Aspect 개념 특징, AOP 용어 정리
1. Spring AOP의 핵심기능과 부가기능 - 업무 로직을 포함하는 기능을 핵심 기능(Core Concerns)- 핵심 기능을 도와주는 부가적인 기능(로깅, 보안)을 부가기능(Cross-cutting Concerns) 이라고 부른다. 2. AOP란?
shlee0882.tistory.com
https://engkimbs.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81AOP
[Spring] 스프링 AOP (Spring AOP) 총정리 : 개념, 프록시 기반 AOP, @AOP
| 스프링 AOP ( Aspect Oriented Programming ) AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이라고 불린다. 관점 지향은 쉽게 말해 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로
engkimbs.tistory.com
https://mangkyu.tistory.com/231
[Spring] AOP Aspect에서 어노테이션 정보나 메소드의 파라미터값 가져오는 방법
Spring 프레임워크를 이용해 공부를 하다보면 AOP를 적용해야 하는 상황이 온다. 그리고 AOP를 적용하다보면 클래스나 메소드에 있는 어노테이션 또는 메소드로 넘겨진 파라미터 값을 필요로 할 때
mangkyu.tistory.com
'Java > AOP' 카테고리의 다른 글
| HttpServletRequestWrapper 에 대해서 ( with. ExceptionHandler) (0) | 2024.08.22 |
|---|---|
| ExceptionHandler (with. AOP) 에 대해서 (0) | 2024.08.21 |