[Spring] AOP란? (Aspect Oriented Programming)
AOP (Aspect Oriented Programming)란? = 관심(Aspect) 지향 프로그래밍 AOP에서 말하는 관심 = 애플리케이션에 필요한 기능 중 공통적으로 적용되는 기능에 대한 관심 공통 관심 사항 & 핵심 관심 사항? 공통
wlikeoxy.tistory.com
에 대한 추가 공부
관점 지향 프로그래밍 = AOP(Aspect Oriented Programming)
: Aspect를 사용하여 다양한 기능들을 분리한다.
(* Aspect? : 하나의 모듈! = 부가 기능, 해당 부가 기능을 어디에 적용할 지 정의한 것)
Aspect = Advice + PointCut
OOP와 대척되는 개념이 아님!
오히려 OOP의 부족한 부분을 보조하는 목적으로 사용됨
횡단 관심사(전체를 관통하는 공통 관심사)를 깔끔하게 처리하기 위함
AOP가 필요한 이유
'객체' 중심 프로그래밍 - OOP : 정의된 기능들을 재사용 하기 위해 등장했다.
OOP의 핵심은 공통된 목적을 띈 데이터와, 동작을 묶어 '하나의 객체'로 정의하는 것이다.
객체를 잘 활용하기 위해서는 관심사 분리(SoC) 디자인 원칙을 준수해야 한다.
그런데 여러 객체들이 만들어지다 보니
특정 객체에 공통적으로 들어가는 부가 기능들이 존재하게 된 것이다.
ex) 트랜잭션, 보안, 로깅 기능 등..
핵심 기능(Core Concerns) : 객체가 제공하는 고유 기능(업무 로직)
횡단 관심사'(Cross-cutting Concerns, 부가기능)
: 업무와는 관련이 없지만 애플리케이션에는 필수적인 부가 기능들
핵심 기능을 보조하기 위해 제공되는 기능 (단독 사용 X)
여러 비즈니스 클래스들에 이 부가 기능들이 각각 포함되어 있다보니
- 메소드 복잡성 증가 ➡ 비즈니스 코드 파악 어려움
- 부가 기능 불특정 다소 메소드 반복 구현 ➡ 횡단 관심사의 모듈화가 어려움
이러한 이유 때문에
부가 기능들을 아예 따로 떼내어서 모듈화 한 것이 바로 AOP 이다!
= OOP 방식의 불필요한 반복을 해결
AOP를 사용하면
비즈니스 코드들에 반복적으로 부가 기능 코드를 넣지 않아도 되고, (중복 코드 제거)
부가 기능의 변경 지점도 한 곳으로 잘 관리될 수 있다. (수정 용이)
AOP 용어 및 개념들
애스펙트 (Aspect)
: 여러 객체에 공통으로 적용되는 기능 (애플리케이션 횡단 기능)
어드바이스 + 포인트컷 을 모듈화
(부가 기능) + (해당 부가 기능을 어디에 적용할 지)
조인 포인트 (join point)
S : 메서드 실행 전의 포인트
E : 메서드 수행 후의 포인트
조인포인트 : S, E와 같이 어드바이스가 적용될 포인트
애플리케이션 실행 흐름에서의 특정 포인트
(클래스 초기화, 객체 인스턴스화, 메소드 호출, 필드 접근, 예외 발생 등)
메소드 실행 지점
어드바이스 (Advice)
: 조인포인트에서 수행되는 코드
: Aspect를 언제 핵심 코드에 적용할지 정의
포인트컷 (Pointcut)
: 조인 포인트 중에서 어드바이스(수행되는 코드)가 적용될 위치를 선별
위빙 (Weaving)
: 어드바이스를 핵심 코드에 적용하는 것
핵심 기능 코드에 영향 X, 부가 기능 추가 가능
AOP 프록시 (proxy)
: AOP 기능을 구현하기 위해 만든 프록시 객체
타겟 (Target)
: 핵심 기능을 담고 있는 모듈
= 부가 기능을 부여할 대상!
Advice를 받는 객체, 포인트 컷으로 결정 됨
어드바이저 (Advisor)
: 1 어드바이스 + 1 포인트 컷
타입별 Advice
어드바이스 Advice
: Aspect를 언제 핵심 코드에 적용할지 정의
특정 조인 포인트에서 애스펙트에 의해 취해지는 조치
Advice 종류
- Before
: 조인 포인트 실행 이전에 실행
@Before("hello.aop.order.aop.Pointcuts.orderAndService()")
public void doBefore(JoinPoint joinPoint) {
log.info("[before] {}", joinPoint.getSignature());
}
- After returning
: 조인 포인트 정상 완료 후 실행
@AfterReturning(value = "hello.aop.order.aop.Pointcuts.orderAndService()", returning = "result")
public void doReturn(JoinPoint joinPoint, Object result) {
log.info("[return] {} return={}", joinPoint.getSignature(), result);
}
- After throwing
: 메서드 예외 던지는 경우에 실행
@AfterThrowing(value = "hello.aop.order.aop.Pointcuts.orderAndService()", throwing = "ex")
public void doThrowing(JoinPoint joinPoint, Exception ex) {
log.info("[ex] {} message={}", joinPoint.getSignature(), ex.getMessage());
}
- After (finally)
: 조인 포인트 동작과는 상관없이 실행
- Around
: 가장 강력한 어드바이스
인 포인트 실행 여부 선택, 반환 값 변환, 예외 변환 등 모든 기능 수행 가능
* 타겟 등 고려해야 할 사항이 있을 때 정상적으로 작동 안될 수도.
but Around를 사용해서 모두 해결하기 보다는
역할을 명확하게 설계 하는 것이 Good.
Pointcut 표현식
포인트 컷 : 관심 조인 포인트를 결정 ➡ 어드바이스 실행 시기 제어할 수 있음
Aspect J pointcut expression -> AspectJ 포인트컷 표현식
ex)
@Pointcut("execution(* transfer(..))") // 포인트컷 표현식
private void anyOldTransfer() {} // 포인트컷 서명
포인트 컷 지시자
: 포인트컷 표현식에서 '포인트컷 지시자'로 시작함 ex) execution
* execution : 메서드 실행 조인트 포인트를 매칭한다.
스프링 AOP에서 가장 많이 사용하며, 기능도 복잡하다.
포인트 컷 표현식
ex) AccountService 인터페이스에 의해 정의된 모든 메소드의 실행
execution(* com.xyz.service.AccountService.*(..))
포인트 컷 결합
: &&, ||, ! 를 사용하여 결합 가능하다
이름으로 참조할 수도 있다.
JointPoint 조인 포인트
: AOP 적용 위치(지점) - 추상적인 개념임
= 프로그램 실행 중 지점 = ex) 어드바이스가 적용될 수 있는 위치, 메소드 실행, 생성자 호출, 필드 값 접근, static 메서드 접근 등
- AspectJ를 사용해서 컴파일 시점과 클래스 로딩 시점에 적용하는 AOP :
바이트코드를 실제 조작하기 때문에 해당 기능을 모든 지점에 다 적용할 수 있습니다.
↕ - 프록시 방식을 사용하는 스프링 AOP : 메서드 실행 지점에만 AOP를 적용할 수 있습니다.
- 프록시는 메서드 오버라이딩 개념으로 동작합니다.
- 생성자나 static 메서드, 필드 값 접근에는 프록시 개념이 적용될 수 없습니다.
- 프록시를 사용하는 스프링 AOP의 조인 포인트는 메서드 실행으로 제한됩니다.
- 프록시 방식을 사용하는 스프링 AOP는 스프링 컨테이너가 관리할 수 있는 스프링 빈에만 AOP를 적용할수 있습니다.
- JoinPoint 메소드는 어드바이스의 종류에 따라 사용방법이 다소 다르지만 기본적으로 어드바이스 메소드에 매개변수로 선언만 하면 됩니다.
* 이미 너무 많은 개념으로 인해 세부사항 생략된 부분😵 :
- execution 외에 언급된 포인트컷 지시자 종류
- 일반적인 pointcut 표현식들
- JoinPoint 인터페이스의 주요 기능
추후에 프로젝트에 AOP 개념 적용시에 더 깊게 공부할 것,,
'Spring' 카테고리의 다른 글
[Spring] Controller 구조 및 핸들러 메서드(Handler Method) (0) | 2022.10.21 |
---|---|
[Spring] Spring MVC란? (0) | 2022.10.21 |
[Spring] Java 기반 컨테이너, Component Scan, 의존 관계 주입 방법 (0) | 2022.10.18 |
[Spring] 스프링 컨테이너(Spring Container), 빈(Bean), 빈스코프(Bean Scope) 란? +싱글톤(Singleton) 스코프 (0) | 2022.10.13 |
[Spring] 아키텍쳐(Architecture)란? / Spring Framework 모듈 구성 보기 (0) | 2022.10.12 |
댓글