AOP란?
어떤 메소드의 실행시간을 측정하려는 요구사항이 있다. 처음에는 하나의 메소드의 시간만 측정하면 됐지만, 점점 많은 수의 메소드를 관리해야 했다.
이렇게 되면 코드의 중복이 많아지고 관리가 힘들어진다. 또한 비즈니스 관심사에 필요하지 않은 실행시간 측정이 비즈니스 코드에 섞이게 된다.
이때 필요한게 AOP 이다.
관점 지향 프로그래밍
AOP
- AOP란 프로그램 구조를 다른 방식으로 생각하게 함으로써 OOP를 보완한다.
- OOP에서 모듈화의 핵심 단위는 클래스이지만 AOP에서 모듈화의 핵심 단위는 관점(aspect)이다.
- 관점은 다양한 타입과 객체에 걸친 트랜잭션 관리같은 관심(concern)을 모듈화할 수 있게 한다.
- crosscutting corncerns: 횡단 관심사
- core concerns: 주요 관심사
AOP 적용
- 횡단 관심사와 주요 관심사를 분리하여 관점별로 각각 기능을 모듈화 할 수 있다.
- 설정을 추가하여 Weaving
AOP 주요 용어
Aspect
- 여러 클래스에 걸친 횡단 관심사의 모듈
- 하나 이상의 Pointcut과 Advice의 조합으로 만들어지는 AOP의 기본 모듈
- Spring framework에서는 @Aspect를 사용하거나 XML에서 설정할 수 있다.
Join Point
- 프로그램 실행 중의 어떤 포인트를 의미 (메소드 실행, Exception 처리 등)
- Pointcut의 후보
- Spring AOP에서는 메소드 실행만 대상.
package org.aspectj.lang;
import org.aspectj.lang.reflect.SourceLocation;
public interface JoinPoint {
String METHOD_EXECUTION = "method-execution";
String METHOD_CALL = "method-call";
String CONSTRUCTOR_EXECUTION = "constructor-execution";
String CONSTRUCTOR_CALL = "constructor-call";
String FIELD_GET = "field-get";
String FIELD_SET = "field-set";
String STATICINITIALIZATION = "staticinitialization";
String PREINITIALIZATION = "preinitialization";
String INITIALIZATION = "initialization";
String EXCEPTION_HANDLER = "exception-handler";
String SYNCHRONIZATION_LOCK = "lock";
String SYNCHRONIZATION_UNLOCK = "unlock";
String ADVICE_EXECUTION = "adviceexecution";
...
}
Advice
- 타겟에 제공할 부가기능을 담은 모듈
- 특정 Join Point에서 Aspect가 취하는 행동
- Ex.) Around, Before, After
Pointcut
- Advice를 적용할 Join Point를 선별하는 작업 또는 그 기능을 적용한 모듈
- Advice는 Pointcut 표현식과 연결되고 Pointcut이 매치한 Join Point에서 실행된다.
Target Object
- 부가기능을 부여할 대상
- 하나 이상의 Aspect가 적용된 객체
AOP Proxy
- 클라이언트와 타겟 사이에 투명하게 존재하면서 부가기능을 제공하는 Object
- Aspect 실행을 휘해 AOP에 의해 생성된 객체
Advisor
- Pointcut과 Advice를 하나씩 갖고 있는 객체
- 스프링 AOP에서만 사용되는 용어이다.
Weaving
- 다른 어플리케이션 타입이나 어드바이즈된 객체를 생성하는 객체와 관점을 연결하는 행위.
Spring AOP 설치
maven
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.10</version>
</dependency>
gradle
implementation 'org.springframework.boot:spring-boot-starter-aop'
2023년 7월 12일 기준 최신버전은 6.0.10
@AspectJ 지원 활성화
- Java Configuration
@Configuration @EnableAspectJAutoProxy public class JavaConfig { ... }
- xml
<aop:aspectj-autoproxy/>
Aspect 선언
AspectJ 지원이 활성화된 상태이어야 한다.
Bean으로 선언하고 @Aspect annotation을 설정하면 해당 스프링빈은 Aspect가 된다.
@Aspect @Component public class SomeAspect { ... }
포인트컷
타겟의 여러 조인포인트 중에 어드바이스를 적용할 대상을 지정하는 키워드
스프링 AOP는 스프링 빈의 메소드 실행 조인포인트만 지원.
포인트컷 선언은 포인트컷 표현식과 포이트컷 시그니쳐로 구성됨.
@Pointcut("execution(public get(..))") // pointcut expression private void some() { // pointcut signature ... }
위의 예제는
some
이 포인트컷의 이름이고 모든 스프링 빈에서의get
메소드 실행에 매칭된다.
포인트컷 - Pointcut Designator
- 스프링 AOP에서 지원하는 포인트컷 지정자 (Pointcut Designator)
execution
- 메소드 실행 조인포인트와 매칭
within
- 주어진 타입으로 조인 포인트 범위를 제한
this
- 주어진 타입을 구현한 AOP Proxy 객체에 매칭
- 보통 Proxy 객체를 Advice 파라미터에 바인딩하는 용도로 사용.
target
- 주어진 타입의 인수를 이용해 매칭
- 보통 타겟 객체를 Advice 파라미터에 바인딩 하는 용도로 사용.
args
- 주어진 타입의 인수를 이용해 매칭
- 메소드 인자를 Advice 파라미터에 바인딩 하는 용도로 사용.
포인트컷 - 표현식 예제
- 모든 public 메소드
execution(public * *(..))
- get~ 으로 시작하는 모든 메소드
execution(* get*(..))
com.abc.def
패키지에 있는 모든 메소드execution(* com.abc.def.*.*(..))
com.abc.service.MemberService
인터페이스에 정의된 모든 메소드execution(com.abc.service.MemberService.*(..))
com.abc.service
패키지의 모든 메소드 실행within(com.abc.service.*)
MemberService
프록시 구현체의 메소드 실행this(com.abc.service.MemberService)
MemberService
인터페이스의 구현 객체의 메소드 실행target(com.abc.service.MemberService)
- 런타임에
Serializable
타입의 단일 파라미터가 전달되는 메소드 실행 (인자값 검사 기능에 많이 사용됨) args(java.io.Serializable)
@Transactional
어노테이션을 가진 모든 타겟 객체의 메소드 실행@target(org.springframework.transaction.annotation.Transactional)
Advice
Advice는 포인트컷과 관련하여 메소드 실행 전, 후, 전/후를 결정하기위해 사용.
Advice 형태 설명 Before Join Point 앞에서 실행할 Advice After Join Point 뒤에서 실행할 Advice AfterReturning Join Point 완전히 정상 종료한 다음 실행하는 Advice Around Join Point 앞과 뒤에서 실행되는 Advice AfterThrowing Join Point에서 예외가 발생했을 때 실행되는 Advice
'Spring' 카테고리의 다른 글
Controller 단위 테스트 시 406 에러 (0) | 2023.03.01 |
---|---|
좋은 객체 지향 설계의 다섯가지 원칙 (SOLID) (0) | 2021.04.23 |
[Spring Framework] @RequestBody와 @ModelAttribute의 차이 (0) | 2021.04.10 |
댓글