티스토리 뷰
1. AOP
:: 관점 지향 프로그래밍(Aspect-Oriented Programming)
:: 애플리케이션에서 부가적인 기능을 모듈화하여 재사용
- 핵심은 1)과 2)의 분리를 통한 수평적 프로그래밍 형성
1) 주요 핵심 기능 : 비즈니스 로직
2) 부가적인 기능 : Logging, Security, Transaction, Exception Handling, Caching 등의 인프라 로직
1.1 용어 정리
구분 | 내용 |
1) Target | - 부가 기능 적용 대상 (클래스, 메서드 등) - Advice가 적용될 실제 객체나 메서드 |
2) Advice | - 부가 기능을 실제로 구현하는 부분 - 부가 기능 구현체 (@Before, @AfterReturning, @AfterThrowing, @After, @Around) |
3) Join Point | - 부가 기능을 적용할 지점 (메서드 호출, 필드 접근 등) - 어디에 적용할 것인가 (메서드, 필드, 생성자) |
4) Pointcut | - 실제 Advice 가 적용될 명세 (Target 선별/필터 명세(정규표현식)) - Ex) execution(* com.example.service.*.*(..)) |
2) Advice 사용
Advice | 내용 |
@Before | - 메소드 호출전 실행 - 실행 로그 기록 및 보안 체크 @Before("execution(* com.example.service.*.*(..))") |
@After | - 메소드 실행 완료 후 실행(메서드의 성공 or 실패에 관계 없이 실행) - 실행 로그 기록 및 보안 체크 @After("execution(* com.example.service.*.*(..))") |
@AfterReturning | - 타겟 메서드의 메소드의 실행 결과에 관 없이 실행 후, 값 반환 @AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result") |
@AfterThrowing | - 타겟 메서드가 예외를 던졌을 때 실행 - 예외 발생 시 로그를 기록하거나 예외 처리 작업 @AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex") |
@Around | - 타겟 메서드 실행 전후에 실행 - 메서드 실행을 제어 가능 @Around("execution(* com.example.service.*.*(..))") |
2. AOP의 종류 - Weaving 유형
:: AOP는 다양한 방식으로 Advice를 Targer에 적용 가능
:: 이를 구현하는 방식에 따라 AOP Weaving 유형이 나뉨
2.1 Compile Time Weaving (CTW)
:: AOP가 컴파일 과정에서 Aspect를 타겟 클래스의 바이트코드에 직접 삽입하는 방식
:: AspectJ에서 제공하며, 컴파일 시점에 Aspect가 실제 코드에 적용(.aj 파일을 통해 AOP를 정의)
:: 실행 시에는 별도의 프록시 객체나 추가적인 조작 없이 이미 바이트코드에 AOP 기능이 적용된 상태로 실행
2.2 Runtime Weaving (RTW)
:: AOP가 런타에 프록시 객체를 생성하여, 타겟 객체의 변형 없이 AOP를 적용하는 방식
:: Spring Framework에서 사용, Spring AOP가 대표적인 예시.
:: JDK 동적 프록시(인터페이스 기반)나 CGLIB(구체 클래스 기반)를 사용하여 프록시 객체 생성
2.3 Load Time Weaving (LTW)
:: 클래스가 메모리에 로드될 때(ClassLoader 시간 / JVM에 로드되는 시간을 의미), AOP 기능을 적용하는 방식
:: AspectJ에서 지원, ClassLoader를 통해 클래스가 메모리에 로드될 때 Aspect를 바이트코드에 적용
2.4 Post-Compile Weaving
:: 컴파일 후에 AOP를 적용하는 방식, 보통 JAR 파일 단위로 AOP 기능을 추가하는 방식
:: AspectJ에서 지원, 컴파일된 후 JAR 파일을 수정하여 Aspect를 추가
2.5 비교
구분 | CTW | RTW | LTW | Post-Complie Weaving |
적용 시점 | 컴파일 시점 | 런타임 시점 | 클래스 로딩 시점 | JAR 파일 배포 후 |
적용 방식 | 바이트코드 직접 삽입 | 프록시 객체 생성 | 클래스 로딩 시 바이트코드 수정 | JAR 파일에 AOP 삽입 |
대표적 도구 | AspectJ | Spring AOP | AspectJ (특수 클래스 로더 필요) |
AspectJ |
성능 | 매우 효율적 | 프록시로 인해 약간의 오버헤드 |
클래스 로딩 시점에서 영향을 미침 | 배포 후 수정 가능 |
장점 | 성능이 우수, 컴파일 시점에서 AOP 적용 | 설정의 용의, 애플리케이션 코드 수정 X | 유연하게 AOP 적용, 운영 중에도 가능 | 배포된 애플리케이션에도 AOP 적용 가능 |
- AspectJ 원리
:: Spring AOP보다 속도와 기능적인 측면에 조금 좋음
:: 바이트코드 조작을 위해 JVM 실행 옵션 변경과 별도의 AJC 컴파일러 사용 필요 (복잡)
:: 컴파일 시점에 바이트 코드를 조작한다는 특징 - Spring AOP 원리
:: 런타임 시점에 별도의 코드 조작없이 자동으로 프록시를 생성하여 Target Object에 부가 기능을 적용
:: Spring AOP가 적용된 Target 메서드를 호출 할 때, 해당 메서드 바로 호출 X,
:: Target 메서드를 감싼 Wrapper Class 가 받아서 Target 메서드를 대신 호출- 런타임 코드 자동생성 기법
1) Java 표준 (인터페이스 기반 프록시 생성) : JDK Dynamic Proxy ← Java Reflection API 활용
2) Spring 표준 (클래스 기반 프록시 생성) : CGLIB ← 직접 바이트코드 조작 (+ Java Reflection API 활용) - AOP 적용을 위해 Proxy 가 필요하니 Proxy Bean 객체 생성 필요
- ProxyFactoryBean :: Proxy Bean 객체를 생성
1) 타겟 객체가 인터페이스를 사용 시, JDK Dynamic Proxy 기반으로 Proxy Bean 을 생성
2) 타겟 객체가 인터페이스 없이 클래스 구현 시, CGLIB 기반으로 Proxy Bean 을 생성
- 런타임 코드 자동생성 기법
- JDK Dynamic Proxy VS CGLIB
분류 | 특징 |
JDK Dynamic Proxy | :: 인터페이스를 구현한 오브젝트에 대해 타겟 클래스(객체)의 인터페이스를 구현 :: 프록시 클래스를 런타임에 동적으로 생성 :: Java Reflection API 활용 |
:: InvocationHandler 로 프록시 구현 :: 인터페이스가 존재하는 경우 사용 |
|
CGLIB |
:: 구체 클래스의 오브젝트에 대해 타겟 클래스(객체)를 상속한 프록시 클래스를 런타임에 동적으로 생성 :: 바이트 코드 직접 조작 :: Java Reflection API 활용도 가능은 함 |
:: MethodInterceptor 로 프록시 구현 :: 인터페이스가 존재하지 않는 경우 사용 |
3. Spring AOP 원리 상세 보기
종류 | 역할 |
TransactionProxyFactoryBean | TransactionInterceptor를 통한 트랜잭션 간접 제어 |
TransactionInterceptor | 트랜잭션을 관리(시작, 실행, 커밋, 롤백 등) |
TransactionAttributes | 트랜잭션 세부적인 설정 관리 |
PlatformTransactionManager | 내부적으로 트랜잭션을 실행(AOP) |
이를 통해 @Transactional 어노테이션 사용 시, Spring은 Proxy 객체를 생성하고 트랜잭션을 관리하는 로직을 적용
트랜잭션 관련 AOP가 적용되어 PlatformTransactionManager를 통해 트랜잭션이 관리
3.1 사용 시, 주의점
- 1) @Transactional 사용 시 주의사항
- 트랜잭션 AOP는 타겟 객체를 상속(extends)하거나 구현(implements)해서 프록시 객체를 생성
- 이후, 프록시 객체를 통해 @Transactional 적용 객체 호출
- 따라서, 트랜잭션 AOP가 적용되려면 프록시 객체를 통해 메서드가 호출되어야 함
- 2) private 메서드와 final 키워드
:: 트랜잭션이 적용될 메서드는 프록시 객체가 메서드를 호출하는 방식으로 동작
- private 메서드는 AOP 프록시에서 접근할 수 없기 때문에
- final 메서드는 재정의가 불가능하므로 AOP 프록시의 가로채기 X
So, private 메서드나 final 메서드는 AOP가 적용될 수 없음을 유의
- 3) 프록시 내부 호출
- 클라이언트가 프록시 객체를 호출하고 트랜잭션이 시작된 후, 프록시 객체의 타겟 메서드를 호출하는 방식
:: 내부 메서드 호출에는 AOP가 적용X - 내부 호출에서 AOP가 동작하지 않는 이유
- 프록시 객체는 클래스나 인터페이스 단위 적용
=> 따라서, 클래스 내부에서 직접 호출하는 메서드에는 AOP가 적용 X - 클래스 내부에서 @Transactional이 적용된 메서드를 호출 시,
=> 해당 메서드는 프록시가 아닌 실제 객체에서 실행되므로 트랜잭션 관리가 적용 X
- 프록시 객체는 클래스나 인터페이스 단위 적용
- 클라이언트가 프록시 객체를 호출하고 트랜잭션이 시작된 후, 프록시 객체의 타겟 메서드를 호출하는 방식
참고
ASAC 수업자료
[Spring] Spring AOP란? Spring AOP는 CTW, PCW, LTW, RTW 중에 무엇일까?
AOP란? AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이라고 불린다. 객체지향을 보완하는 수단으로 흩어진 관점(Aspect)를 모듈화 하여 비즈니스 로직을 해치지 않고 재사용 하는 프로
syongsyong2.tistory.com
'정리용 > DB' 카테고리의 다른 글
[DB 기초] 10. JPA 연관관계 어노테이션 (0) | 2025.04.19 |
---|---|
[DB 기초] 9. ORM / JPA (0) | 2025.04.17 |
[DB 기초] 7-2. 선언형 트랜잭션의 주의점 (0) | 2025.03.25 |
[DB 기초] 7-1. Spring Transaction 방법 2가지 : 프로그래밍형 / 선언형 (0) | 2025.03.24 |
[DB 기초] 7. 트랜잭션 - 동기화와 추상화 (0) | 2025.03.24 |
- Total
- Today
- Yesterday
- asac7
- useReducer
- ssh
- useEffect
- git
- asac7#asac
- ASAC
- useContext
- useMemo
- acac
- useCallback
- memo
- Nginx
- acas#acas7기
- react
- useState
- asac7기
- useRef
- useLayoutEffect
- asac#asac7기
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |