728x90
반응형
AOP를 사용할 때 부가 기능 로직은 어떤 방식으로 실제 로직에 추가될 수 있을까?
1. 컴파일 시점
- .java → .class 이 시점에 부가 기능 로직 추가 가능
- AspectJ 컴파일러는 Aspect를 확인해서 해당 클래스가 적용 대상인지 먼저 확인하고, 적용 대상인 경우 부가 기능 로직을 적용한다.
- 위빙(Weaving): 애스펙트와 실제 코드를 연결해서 붙이는 것 (원본 로직에 부가 기능 로직 추가)
- 단점: 특별한 컴파일러도 필요하고 복잡하다.
2. 클래스 로딩 시점
- .class 파일을 JVM 내부 클래스 로더에 보관할 때 이 .class 파일을 조작한 다음 JVM에 올릴 수 있다.
- 로드 타임 위빙
- 단점: 자바 실행할 때 특별한 옵션(java -javaagent)을 통해 클래스 로더 조작기를 지정해야하는데, 이 부분이 번거롭고 운영하기 어렵다.
3. 런타임 시점(프록시)
- 런타임 시점은 컴파일도 다 끝나고, 클래스 로더에 클래스도 다 올라가서 이미 자바가 실행되고 난 다음, 자바 메인 메서드가 이미 실행된 다음
- 자바 언어가 제공하는 범위 안에서 부가기능 적용
- 스프링 같은 컨테이너 도움 받고 프록시, DI, 빈 포스트 프로세서 같은 개념 총 동원
- 프록시를 통해 스프링 빈에 부가 기능 적용 가능
- 프록시를 사용하기에 AOP 기능에 일부 제약(final, 생성장 등)이 있다. 특별한 컴파일러나, 자바를 실행할 때 복잡한 옵션과 클래스 로더 조작기를 설정하지 않아도 된다.
- 스프링만 있으면 얼마든지 AOP를 적용 가능
부가 기능이 적용되는 차이
- 컴파일 시점: 실제 대상 코드에 애스팩트를 통한 부가 기능 호출 코드가 포함된다. AspectJ를 직접 사용해야 한다.
- 클래스 로딩 시점: 실제 대상 코드에 애스팩트를 통한 부가 기능 호출 코드가 포함된다. AspectJ를 직접 사용해야 한다.
- 런타임 시점: 실제 대상 코드는 그대로 유지된다. 대신에 프록시를 통해 부가 기능이 적용된다. 따라서 항상 프록시를 통해야 부가 기능을 사용할 수 있다. 스프링 AOP는 이 방식을 사용한다.
AOP 적용
- 적용 가능 지점(조인 포인트): 생성자, 필드 값 접근, static 메서드 접근, 메서드 실행
- AOP를 적용할 수 있는 지점을 조인 포인트라 한다.
- AspectJ를 사용해서 컴파일 시점과 클래스 로딩 시점에 적용하는 AOP는 바이트코드를 실제 조작하기 때문에 해당 기능을 모든 지점에 다 적용할 수 있다.
- 프록시 방식을 사용하는 스프링 AOP는 메서드 실행 지점에만 적용 가능
- 프록시는 메서드 오버라이딩 개념으로 동작 → static 메서드, 필드값 접근에는 프록시 개념 적용 불가능
- 프록시를 사용하는 스프링 AOP의 조인 포인트는 메서드 실행으로 제한됨
- 프록시 방식을 사용하는 스프링 AOP는 스프링 컨테이너가 관리할 수 있는 스프링 빈에만 AOP를 적용할 수 있음
더보기
💡 스프링은 AspectJ의 문법을 차용하고 프록시 방식의 AOP를 적용한다. AspectJ를 직접 사용하는 것이 아니다.
그렇다면 스프링 AOP 보다는 더 기능이 많은 AspectJ를 직접 사용해서 AOP를 적용하는 것이 더 좋지 않을까?
AspectJ를 사용하려면 공부할 내용도 많고, 자바 관련 설정(특별한 컴파일러, AspectJ 전용 문법, 자바 실행 옵션)도 복잡하다. 반면에 스프링 AOP는 별도의 추가 자바 설정 없이 스프링만 있으면 편리하게 AOP를 사용할 수 있다. 실무에서는 스프링이 제공하는 AOP 기능만 사용해도 대부분의 문제를 해결할 수 있다. 따라서 스프링 AOP가 제공하는 기능을 학습하는 것에 집중하자.
728x90
반응형
댓글