Tech/Spring

AOP 적용 방식

봄의 개발자 2023. 10. 16.
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
반응형

댓글