관점 지향 프로그래밍(AOP)

황승현·2024년 1월 17일
0

스프링 강의 정리

목록 보기
8/8

AOP(Aspect-Oriented Programming)

핵심 로직과 부가기능을 분리하고, 부가 기능을 모듈화하여 애플리케이션 전체에 걸쳐 재사용할 수 있도록 하는 프로그램 패러다임

객체지향 프로그래밍(OOP)와의 관계

  • 객체지향 프로그래밍(OOP)

    • 비즈니스 로직을 모듈화하여 객체별로 역할을 정의

    • 다수의 객체들에 분산되어 중복적으로 존재하는 공통 관심사가 존재하며, 이것은 프로그램을 복잡하게 만들고, 코드의 변경을 어렵게 한다.

  • 관점지향 프로그래밍(AOP)

    • 객체지향 프로그래밍의 공통 관심사가 중복적으로 존재한다는 문제점을 보완하기 위해 나온 개념

    • 기존 OOP에서 핵심 관심사를 분리하여 프로그램 모듈화를 향상시키는 프로그래밍 스타일

    • 객체 혹은 메소드 별로 필요한 부가적인 기능들을 모듈화, OOP와 함께 적용 가능

    • AOP는 객체를 핵심 관심사와 횡단 관심사로 분리

      • 핵심 관심사 = 핵심 로직

      • 횡단 관심사(Cross-Cutting Concern) = 부가 기능, 관점(Aspect)이라는 모듈로 정의하고 핵심 관심사와 엮어서 처리

부가 기능의 예

  • 로깅, 보안, 트랜잭션 관리 등이 존재한다.

  • Spring에서는 @Transactional 어노테이션을 사용하면, 트랜잭션 단위로 묶여서 동작

만약 @Transactional 어노테이션이 없었다면 DB와 연동하는 Service 레이어의 모든 메소드마다 아래 코드를 작성해야 됨

@Transactional 어노테이션은 메소드마다 필요한 부가 기능(여기서는 트랜잭션 처리)을 모듈화한 것!

class SomeService {

   fun doTransaction() {
			  val tx = em.getTransaction(); //Transaction을 가져옴
	      tx.begin(); //트랜잭션 시작
        ... 
        // DB 관련 로직
	      ...
	      tx.commit(); //commit해서 트랜잭션 종료
	 
   }
}

AOP의 주요 개념

  • 관점(Aspect)

    • 구현하고자 하는 횡단 관심사의 기능

    • 횡단 관심사(부가기능)를 모듈화한 단위

    • Advice와 PointCut을 합친 것

  • 충고(Advice)

    • 실질적으로 부가기능이 정의되어 있는 객체
  • 포인트컷(PointCut)

    • Aspect가 적용될 프로그램상 실제 위치
  • 결합점(JoinPoint)

    • PointCut의 후보군

    • Aspect가 적용될 수 있는 위치

    • 메소드가 호출되는 시점, 클래스의 생성자가 호출되는 시점, exception이 발생하는 시점, argument로 넘어오는 시점 등 애플리케이션 코드 내의 어디든지 적용이 가능

  • 엮기(Weaving)

    • 관점(Aspect)을 실제 코드에 적용하는 과정을 나타낸 것

    • Compile-time Weaving

      • AOP가 적용되어 있는 지 확인하고, 컴파일 시점에 AOP가 적용된 클래스로 바꿔주는 방법 (클래스 자체를 변경)

      • 예를 들어 Service 클래스 내부의 어떤 메소드 위에 @Transactional을 붙였다고 가정함. 컴파일 시점에 컴파일러가 검사를 하다가@Transactional을 확인하면 Service 클래스를 doTransaction()이 포함된 클래스로 바꿔줌

    • Load-time Weaving

      • Java 기반 프로그램은 컴파일 후, 클래스 자체를 로딩하는 시점이 존재

      • 이때 클래스가 자바 가상 머신이 이해할 수 있는 Byte Code라는 것으로 변경됨

      • JVM이 클래스를 로딩할 때 해당 클래스의 Byte Code를 변경하여 원본 클래스를 바꾸지 않고, AOP를 적용

    • Run-time Weaving

      • 컴파일시점이나 로딩 시점 전부 아무 짓도 안 함

      • 애플리케이션이 실행될 때 프록시 객체를 사용하여 실제 객체에 접근

      • 예를 들어 Service 클래스 내부의 어떤 메소드 위에 @Transactional을 붙였다고 가정함. 런타임 시점에 @Transactional 역할을 수행할 프록시라는 가짜 객체가 생성됨. Controller에서 Service 레이어에 접근할 때 @Transactional 역할을 담당하는 프록시 객체를 통해 Transactional 기능을 수행한 후, Service 클래스로 접근함

  • AOP 프록시(Proxy)

    • 대상 객체(Target Object)에 Advice가 적용된 후 생성되는 객체

    • 실제 객체에 접근할 때 사용할 부가기능이 정의되어 있는 가짜 객체

  • 대상 객체(Target Object)

    • Advice를 받는 객체, Spring AOP는 Run-time Weaving을 지원하기 때문에 대상 객체는 항상 프록시 객체가 된다.

쉽게 말해 AOP란 부가 기능을 모듈화하고, 내 애플리케이션 코드 중에 적용할 부분을 찾아 적용하는 것!

Java 진영의 AOP 프레임워크

  • 대표적으로 Spring AOP와 AspectJ로 나뉜다.

  • 두 프레임워크의 가장 큰 차이점은 실제 코드에 적용하는 방법(Weaving)이 다르다는 것이다!

Spring AOP

  • Run-time Weaving만 지원

  • 런타임 때 프록시를 만들고, 이 프록시를 거쳐가며 동작하기 때문에 오버헤드가 존재 (시간이 더 걸린다.)

  • 일반 메소드만 JoinPoint로 사용할 수 있다.

    • 항상 프록시에 해당하는 클래스를 만들어야 한다.

    • 이때 Aspect를 적용하려는 Class가 final class일 경우(상속을 받을 수 없는 클래스일 경우) Aspect를 적용할 수 없다.

    • Java의 final 또는 static method에도 적용되지 않는다.

  • Aspect를 적용할 때 Spring에서 관리하는 Bean에만 적용이 가능하다.

  • Spring AOP는 AOP를 간단하게 만들겠다는 것이 목표이기 때문에 특정 경우에만 사용이 가능하다.

    • 프록시 객체를 만들게끔 Aspect를 정의하면 끝남

    • 일반 메소드만 가능 Bean에서만 동작 가능

AspectJ

  • Compile Time Weaving과 Load-time Weaving을 지원

  • 컴파일 또는 클래스를 로딩할 때 미리 만들기 때문에 Spring AOP에 비해 8~35배 정도 빠르다.

  • 클래스를 변경하거나 Byte Code를 변경하기 때문에 모든 부분에 JoinPoint를 적용할 수 있다. (어디든지 Aspect를 적용할 수 있다.)

  • AspectJ는 컴파일 시점에 할지, 클래스를 로드할 때 할지 결정해야하기 때문에 별도의 컴파일러나 weaver가 필요하므로, Spring AOP에 비해 복잡하다.

참고문헌

https://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte2:fdl:aop

0개의 댓글