트랜잭션과 같은 '인프라 로직'은 애플리케이션 전 영역에서 나타날 수 있음
이런 중복코드는 유지보수를 힘들게 만듦. 또한 비즈니스 로직과 함께 있어 비즈니스 로직을 이해하기 어려워짐
'성능검사', '로깅', '트랜잭션'과 같은 인프라로직은 비즈니스 로직과는 관심이 다르고, 중복이 횡단으로 나타난다.
Aspect-Oriented Programming
관점지향 프로그래밍이란 '횡단 관심'에 따라 프로그래밍을 하는 것
AOP는 OOP를 대체하는 프로그래밍이 아니라 OOP를 보완하는 것
AOP는 일종의 패러다임. 각 언어마다 AOP의 구현체들이 있음
자바은 AspectJ를 사용하고 있음
AOP는 횡단의 관심을 가지기 때문에 '어떤 부가기능'을 '어디에 적용할 것인가'를 고민해야 한다.
이런 AOP와 관련된 용어를 몇개 알아보자
어떤 대상에 부가 기능을 부여할 것인가?
언제 공통 관심 기능을 핵심 로직에 적용할지 정의.
Before, AfterReturning, AfterThrowing, After, Around
Advice를 적용 가능한 지점을 의미. 메서드 호출, 필드 값 변경 등이 해당됨
스프링은 프록시를 이용해 AOP를 구현하기 때문에 메서드 호출에 대한 Joinpoint만 지원
Join point의 부분 집합. 실제 Advice가 적용되는 지점
스프링이 아닌 AOP 패러다임에 관한 이야기
java파일을 class파일로 컴파일하는 시점에 aspect들을 끼워 넣어주어 AOP를 적용시키는 방식
class파일을 메모리상에 올릴 때 AOP를 적용시키는 방식
스프링 AOP에서 사용하는 방식
타겟 클래스를 프록시로 감싸서 부가기능을 제공하는 방식. Spring은 IOC와 DI를 기반으로 하기 때문에 가능한 방식
적용할 수 없음. private 객체는 같은 객체 내에서 호출되는데 이땐 proxy 객체가 아니라 원래 객체를 호출하는 것이라 AOP가 적용되지 않음.
외부에서 호출해주는 메서드만(public) 프록시 객체를 통해 실행되기 때문에 AOP가 적용됨
Spring AOP
간단한 AOP 기능 제공
AspectJ
완벽한 AOP 기능 제공
Spring AOP
메서드 레벨만 지원
AspectJ
생성자, 필드, 메서드 등 다양하게 지원
Spring AOP
런타임 시에만 가능. Spring 컨테이너가 객체 생성을 관리하기 때문에 가능한 것(DI, IoC를 통해 이루어짐)
AspectJ
런타임은 제공하지 않음. DI, IoC가 없으므로
대신 compile-time, post-compile, load-time 제공
Spring AOP
Spring Container가 관리하는 Bean에만 가능. Spring 컨테이너를 통해 이루어지기 떄문에
AspectJ
모든 Java object에 가능
Spring AOP에선 자기가 자기 메서드를 호출할 때 AOP가 적용 안됨