[Spring.5] Aspect Oriented Programming, AOP

AOP AOP


정의

AOP(Aspect Oriented Programming)
주요 관심사를 제외한 ‘공통’ 요소를 빼서 모듈화 한 프로그래밍 기법이다.
오브젝트가 원래 하는 일을 주요 관심사(비즈니스 로직, 서비스 로직)라고 하는데, 주요관심사 이외의 것들 중 여러 오브젝트에 공통으로 들어있는 요소를 빼서 모듈화하는 방법이다.
공통으로 나타나는 부분을 ‘횡단 관심사(cross-cutting concern) 이라고 한다.
예를 들어, Transaction, logging 등을 AOP로 한 번에 처리할 수 있다.
DI(Dependency Injection)가 의존성 주입이라면, AOP는 로직을 주입하는 것이라고 할 수 있다.

속성/기술

AOP기술을 설명할 때에 5가지 용어를 이해해야 한다.

PointCut

Aspect 적용 위치 지정자. 횡단 관심사를 적용할 타깃 메서드를 선정하는 필터. PointCut에 의해 걸러진 메서드에만 AOP가 적용되게 된다.

Advice

PointCut에 적용할 로직. PointCut에 의해 걸러진 메소드들에 ‘언제’, ‘무슨’로직을 주입할 것인가.
메소드 실행 전/후/실행 에러가 났을 때에 등 메소드 실행 전 후를 기준으로 언제 어떤 로직을 주입할 것인가에 대한 설정.

Joint Point

A클래스가 B클래스를 호출할 때에 호출하는 그 시점이 Join Point이다. 스프링에서는 메소드의 실행 및 반환 시점이 Join Point이다. Point Cut은 Join Point에서 Advice를 실행할 필터이다.

Advice

하려는 기능이 구현된 컴포넌트이다. (로그, 트랜잭션 등)

Aspect

이 모든 것들이 포함되어 있는 것을 일컫는다. 즉, Aspect = Join Point 중 Pointcut에서 Advice 수행. 또한 Advice Type에는 실행 시점(경우)에 따른 @Before, @After, @AfterReturning, @AfterThrowing, @Around 5개의 Advice가 있다.

특성

핵심로직에 횡단 관심사를 주입하는 것을 Weaving이라고 하는데, Weaving 되는 방식에는 크게 세 가지가 있다.

1) 핵심 로직을 구현한 코드(클래스)를 컴파일할 때

AspectJ에서 주로 사용하는 방식. AspectJ에서 AOP를 주입시켜주는 컴파일러나 IDE를 함께 제공한다.

2) 컴파일 된 클래스를 로딩할 때

JVM이 클래스를 로딩할 때에 클래스 정보를 변경할 수 있는 에이전트 제공.

3) 로딩한 클래스의 객체를 생성할 때.

소스코드/클래스 정보 자체를 변경하지 않고 프록시 객체를 생성하여 핵심 로직을 구현한 객체에 접근한다.

스프링에서는 기본적으로 ‘3) 프록시’ 방법을 제공한다. 컨테이너를 초기화하는 과정에서 설정 정보에 지정한 빈 객체에 대한 프록시 객체를 생성한다. 그리고 원본 빈 객체 대신 프록시 객체를 사용하도록 의존성을 주입시킨다.

인터페이스 기반 프록시 생성이기 때문에 인터페이스에 정의되어 있지 않은 메서드에 대해서는 AOP가 적용되지 않는다.
인터페이스를 구현하지 않은 객체에 AOP를 적용하려면 CGLIB를 이용한 클래스를 사용하여 AOP를 적용시킨다.

Spring AOP는 proxy-based라는 것은 스프링 디자인 패턴에서 매우 중요하다.

proxy는 소프트웨어 디자인 패턴인데, 두 오브젝트가 직접연결이 아닌 중간에 매개 객체를 두어서 연결시키는 패턴이다. 즉, A ObjectB Object 를 콜 할 때 직접 호출하는 것이 아닌 B' Object를 호출하고 B’ Object(프록시 객체)가 중간에 가로채서 B Object를 호출하는 것이다. (A object -> B' object -> B object)
스프링 AOP에서는 기본적으로 AOP 설정을 하면, proxy 객체를 생성하여 proxy 객체가 핵심업무(주요관심사, 비즈니스로직)과 더불어 공통 업무를 수행하도록 한다. 그래서 AOP를 사용하기 위해서 클래스들 사이에 강한 결합이 아닌 약한 결합 즉, 인터페이스 기반으로 설계해야 한다.