AOP (Aspect Oriented Programming)
AOP는 Aspect Oriented Programming의 약자이며 관점 지향 프로그래밍이라고 한다. 로직을 핵심적인 관점 및 부가적인 관점으로 나눠 그 관점(Aspect)을 기준으로 각각 모듈화하는 개발 방법이다.
핵심적인 관점은 핵심 비즈니스 로직을 말하며, 부가적인 관점은 어플리케이션에서 공통적으로 발생하는 부가적인 작업을 의미한다. 이러한 부가 작업에는 로깅, 트랜잭션 관리, 보안, 캐싱 등 다양한 측면을 포함할 수 있다.
개발을 진행하다 보면 반복해서 사용해야 하는 코드들이 있다.
아래 예시에서 사용자 정보를 불러오는 UserService와 메일 정보를 불러오는 MailService는 핵심 기능 관점에서는 공통 요소가 없다.
하지만 부가적인 관점에서 보면 각 서비스의 메인 메서드(getXXX) 호출 전후 before/after 메서드가 공통인 것을 확인할 수 있다.
이 부분을 추출해서 모듈화하는 것이다.
위 이미지처럼 가로 영역의 공통 부분을 추출했다고 해서 이걸 흩어진 관심사 혹은 횡단 관심사(Cross-cutting Concern)라고 한다. 이 공통적으로 발생하는 기능을 분리하는 작업, 즉, 직접 로직에 추가하지 않고 Aspect로 모듈화해서 분리해서 재사용하는 것이 핵심이다.
위 예시를 토대로 더 자세히 설명하자면,
1. 내 정보(사용자 정보)를 조회하는 기능
2. 내 메일을 조회하는 기능
은 핵심적인 관심 사항이다.
반면,
1. 정보를 조회하기 전 권한을 확인하는 일
2. 조회 후 로그를 남기는 일
등의 일은 어플리케이션에서 공통적으로 적용되는 기능이므로 부가 작업이다.
AOP 적용 방식
AOP 적용 방법에는 크게 세가지가 있다.
- 컴파일 시점 적용
: 컴파일 시점에 바이트 코드를 조작하여 AOP가 적용된 바이트 코드를 생성 - 클래스 로드 타임 적용
: 컴파일 뒤 클래스 로딩 시점에 클래스 정보를 변경하는 방법 - 런타임 적용
: 런타임에 프록시 객체를 생성하여 프록시 빈이 Aspect 코드를 추가하여 동작하는 방법
이 중 스프링 AOP에서 주로 사용하는 방식은 세번째 '런타임 시점 적용'이다.
Spring AOP
스프링에서 제공하는 스프링 AOP에서는 프록시 패턴을 기반으로 하여 AOP를 구현하고 있다.
런타임에 대상 객체를 감싸는 프록시 객체를 생성하여 공통 관심사를 처리한다. 프록시는 메서드 오버라이딩 개념으로 동작하므로 메서드에서만 적용이 가능하다. 따라서 스프링 Bean에만 AOP 적용 가능하다.
특별한 컴파일 과정이 필요하지 않다.
(프록시 패턴에 대해서는 나중에 추가해보겠음 .....)
AOP 주요 개념
- JoinPoint(조인 포인트)
- 관점이 적용될 수 있는 특정 지점
- ex. 메서드 실행, 예외 발생, 필드 접근 등
- 스프링 AOP는 프록시 기반이기 때문에 항상 메서드 실행 지점
- Advice(어드바이스)
- 조인포인트에서 실행되는 실제 동작
- 실제로 수행하는 기능을 구현한다.
- ex. 메서드 실행 전 로깅하는 Advice 등
- 스프링 AOP는 프록시 기반이기 때문에 조인포인트가 메서드 실행 시점 뿐이고 포인트컷도 메서드 실행 시점만 가능
- Pointcut(포인트컷)
- 조인포인트의 상세 스펙 정의
- 어떤 joinpoint를 어떤 advice로 연결할 것인가를 정의한다.
- 특정한 조인 포인트를 선택하기 위한 규칙을 포인트컷 표현식을 통해 정의할 수 있다.
- Aspect(관점)
- 흩어진 관심사를 정의하는 모듈
- advice + pointcut을 모듈화 한 것으로 주로 공통적인 기능이나 부가 작업을 구현한다
- ex. 로깅을 담당하는 Aspect, 트랜잭션을 관리하는 Aspect 등
구체적인 구현 과정에 대해서는 다음 페이지에 작성해야지
[참고]