Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
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
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

[AOP] AOP 적용 방식 본문

인프런/[인프런] 스프링 핵심 원리 - 고급

[AOP] AOP 적용 방식

Seung__ 2022. 1. 5. 13:02
  • AOP를 사용하면 핵심 기능과 부가 기능이 코드상 완전히 분리되어서 관리된다.
  • 그렇다면 AOP를 사용할 때 부가 기능 로직은 어떤 방식으로 실제 로직에 추가될 수 있을까?????
  • 3가지 방법
    컴파일 시점
    클래스 로딩 시점
    런타임 시점(프록시) --> 지금까지 한거

 

1. 컴파일 시점 : AspectJ 사용


  • .java 소스 코드를 컴파일러를 사용해서 .class 를 만드는 시점에 부가 기능 로직을 추가할 수 있다.
  • 이때는 AspectJ가 제공하는 특별한 컴파일러를 사용해야 한다. 
  • 컴파일 된 .class 를 디컴파일 해보면 애스펙트 관련 호출 코드가 들어간다. 
  • 한 마디로 부가 기능 코드가 핵심 기능이 있는 컴파일된 코드 주변에 실제로 붙어 버린다고 생각하면 된다. 
  • AspectJ 컴파일러는 Aspect를 확인해서 해당 클래스가 적용 대상인지 먼저 확인하고, 
  • 적용 대상인 경우에 부가 기능 로직을 적용한다.
  • 참고로 이렇게 원본 로직에 부가 기능 로직이 추가되는 것을 위빙(Weaving)이라 한다.
  • Weaving: 옷감을 짜다. 직조하다. 애스펙트와 실제 코드를 연결해서 붙이는 것

  • 단점
    컴파일 시점에 부가 기능을 적용하려면 특별한 컴파일러도 필요하고 복잡하다.

 

2. 클래스 로딩 시점: AspectJ 사용


  • 자바를 실행하면 자바 언어는 .class 파일을 JVM 내부의 클래스 로더에 보관한다. 
  • 이때 중간에서 .class 파일을 조작한 다음 JVM에 올릴 수 있다. 
  • 자바 언어는 .class 를 JVM에 저장하기 전에 조작할 수 있는 기능을 제공한다. 
  • 궁금한 분은 java Instrumentation를 검색해보자. 참고로 수 많은 모니터링 툴들이 이 방식을 사용한다. 
  • 이 시점에 애스펙트를 적용하는 것을 로드 타임 위빙이라 한다.

  • 단점
    로드 타임 위빙은 자바를 실행할 때 특별한 옵션( java -javaagent )을 통해 
    클래스 로더 조작기를 지정해야 하는데, 이 부분이 번거롭고 운영하기 어렵다.

 

 

3. 런타임 시점


  • 런타임 시점은 컴파일도 다 끝나고, 클래스 로더에 클래스도 다 올라가서 이미 자바가 실행되고 난 다음. 
  • 자바의 메인( main ) 메서드가 이미 실행된 다음이다. 
  • 따라서 자바 언어가 제공하는 범위 안에서 부가 기능을 적용해야 한다. 
  • 스프링과 같은 컨테이너의 도움을 받고 프록시와 DI, 빈 포스트 프로세서 같은 개념들을 총 동원해야 한다.
  • 이렇게 하면 최종적으로 프록시를 통해 스프링 빈에 부가 기능을 적용할 수 있다.
  • 지금까지 우리가 학습한 것이 바로 프록시 방식의 AOP이다.
  • 프록시를 사용하기 때문에 AOP 기능에 일부 제약이 있다. 
  • 하지만 특별한 컴파일러나, 자바를 실행할 때 복잡한 옵션과 클래스 로더 조작기를 설정하지 않아도 된다.
  • 스프링만 있으면 얼마든지 AOP를 적용할 수 있다.

 

 

4. 세 가지 방식의 차이


  • 컴파일 시점
    실제 대상 코드에 애스팩트를 통한 부가 기능 호출 코드가 포함된다. AspectJ를 직접 사용해야 한다.
  • 클래스 로딩 시점
    실제 대상 코드에 애스팩트를 통한 부가 기능 호출 코드가 포함된다. AspectJ를 직접 사용해야 한다.
  • 런타임 시점
    실제 대상 코드는 그대로 유지된다. 대신에 프록시를 통해 부가 기능이 적용된다.
    따라서 항상 프록시를 통해야 부가 기능을 사용할 수 있다. 스프링 AOP는 이 방식을 사용한다.

 

 

5. AOP 적용 위치


AOP는 지금까지 학습한 메서드 실행 위치 뿐만 아니라 다음과 같은 다양한 위치에 적용할 수 있다.

  • 적용 가능 지점(조인 포인트)
    생성자, 필드 값 접근, static 메서드 접근, 메서드 실행
    이렇게 AOP를 적용할 수 있는 지점을 조인 포인트(Join point)라 한다.
  • AspectJ를 사용해서 컴파일 시점과 클래스 로딩 시점에 적용하는 AOP는 
    바이트코드를 실제 조작하기 때문에 해당 기능을 모든 지점에 다 적용할 수 있다.
  • 그런데 프록시 방식을 사용하는 스프링 AOP는 메서드 실행 지점에만 AOP를 적용할 수 있다.
    프록시는 메서드 오버라이딩 개념으로 동작한다. 
    • 따라서 생성자나 static 메서드, 필드 값 접근에는 프록시 개념이 적용될 수 없다.
    • 프록시를 사용하는 스프링 AOP의 조인 포인트는 메서드 실행으로 제한된다.
  • 프록시 방식을 사용하는 스프링 AOP는 스프링 컨테이너가 관리할 수 있는 스프링 빈에만 AOP를 적용
    수 있다.
  • 즉 스프링 빈으로 등록해야 스프링 AOP 적용 가능
  • 참고
    스프링은 AspectJ의 문법을 차용하고 프록시 방식의 AOP를 적용한다. 
    AspectJ를 직접 사용하는 것이 아니다.
  • 중요
스프링이 제공하는 AOP는 프록시를 사용한다. 따라서 프록시를 통해 메서드를 실행하는 시점에만 AOP가 적용된다. AspectJ를 사용하면 앞서 설명한 것 처럼 더 복잡하고 더 다양한 기능을 사용할 수 있다.
그렇다면 스프링 AOP 보다는 더 기능이 많은 AspectJ를 직접 사용해서 AOP를 적용하는 것이 더 좋지 않음???
AspectJ를 사용하려면 자바 관련 설정(특별한 컴파일러, AspectJ 전용 문법, 자바 실행 옵션) 복잡하다.
반면에 스프링 AOP는 별도의 추가 자바 설정 없이 스프링만 있으면 편리하게 AOP 를 사용할 수 있다.
실무에서는 스프링이 제공하는 AOP 기능만 사용해도 대부문의 문제를 해결할 수 있다.

'인프런 > [인프런] 스프링 핵심 원리 - 고급' 카테고리의 다른 글

[스프링AOP] 프로젝트 생성  (0) 2022.01.05
[AOP] AOP 용어 정리  (0) 2022.01.05
[AOP] Aspect  (0) 2022.01.05
[AOP] 핵심 기능과 부가 기능  (0) 2022.01.05
[@AspectAOP] @Aspect Proxy  (0) 2022.01.05
Comments