-
AOP란?
AOP는 흔히 '관점 지향 프로그래밍' 이라고 불린다. 이때 '관점(Aspect)'이라는 용어는 개발자들에게 '관심사(concern)'라는 말로 통용된다. '관심사'는 개발 시 필요한 고민이나 염두에 두어야 하는 일이라고 생각할 수 있다. 예를들어
- 파라미터가 올바르게 들어왔을가?
- 이 작업을 하는 사용자가 적절한 권한을 가진 사용자인가?
- 이 작업에서 발생할 수 있는 모든 예외는 어떻게 처리해야 하는가?위와 같은 고민들은 '핵심 로직'은 아니지만, 코드를 온전하게 만들기 위해 필요한 고민들이다. 전통적인 방식에서는 개발자가 반복적으로 이러한 고민들을 코드에 반영하게 된다. AOP는 이러한 고민에 대한 문제를 조금 다른 방식으로 접근한다. AOP가 추구하는 것은 '관심사의 분리(seperate concerns)'이다. AOP는 개발자가 염두에 두어야 하는 일들을 별도의 '관심사'로 분리하고, 핵심 비즈니스 로직만을 작성할 것을 권장한다.
예를 들어 나눗셈을 구현한다고 치면 '핵심 로직'은 두 개의 숫자를 나누는 것이지만, '주변 로직'은 0을 나누는 것이 아닌지 등 체크하는 것이다. '관심사'는 바로 이런 가장 중요한 로직은 아니지만, 사전 조건이나 사후 조건 등이라고 간주할 수 있다.
AOP는 과거에 개발자가 작성했던 '관심사+비즈니스 로직'을 분리해서 별도의 코드로 작성하도록 하고, 실행할 때 이를 결합하는 방식으로 접근한다. 과거에 비즈니스 로직을 작성하면서 그 내부에 필요한 '관심사'를 처리하던 방식과 정반대의 접근 방식이라고 볼 수 있는데, 개발자가 작성한 코드와 분리된 관심사를 구현한 코드를 컴파일 혹은 실행 시점에서 결합시킨다. 실제 실행은 결합된 상태의 코드가 실행되기 때문에 개발자들은 핵심 비즈니스 로직에만 근거해서 코드를 작성하고, 나머지는 어떤 관심사들과 결합할 것인지를 설정하는 것 만으로 모든 개발을 마칠 수 있게 된다.
예를 들어 AOP를 이용하면 작성된 모든 메서드의 실행 시간이 얼마인지를 기록하는 기능을 기존 코드의 수정 없이도 작성할 수 있고, 잘못된 파라미터가 들어와 예외가 발생하는 상황을 기존 코드의 수정 없이 제어할 수 있다. 스프링이 AOP를 지원한다는 것이 스프링의 가장 중요한 특징 중 하나라는 이유 역시 별도의 복잡한 설정이나 제약 없이 스프링 내에서 간편하게 AOP 기능을 구현할 수 있기 때문이다.
AOP 용어들
AOP는 기존의 코드를 수정하지 않고, 원하는 기능들과 결합할 수 있는 패러다임이다.
개발자의 입장에서 AOP를 적용한다는 것은 기존의 코드를 수정하지 않고도 원하는 관심사(cross-concern)들을 엮을 수 있다는 점이다. 위의 그림에서 Target에 해당하는 것이 바로 개발자가 작성한 핵심 비즈니스 로직을 가지는 객체이다.
Target은 순수한 비즈니스 로직을 의미하고, 어떠한 관심사들과도 관계를 맺지 않는다. 순수한 코어(core)라고 볼 수 있다. Target을 전체적으로 감싸고 있는 존재를 Proxy라고 한다. Proxy는 Target을 호출하지만, 중간에 필요한 관심사들을 거쳐 Target을 호출하도록 자동 혹은 수동으로 작성된다. Proxy의 존재는 직접 코드를 통해 구현하는 경우도 있지만, 대부분 스프링 AOP 기능을 이용해 자동으로 생성되는(auto-proxy)방식을 이용한다. JoinPoint는 Target 객체가 가진 메서드이다. 외부의 호출은 Proxy 객체를 통해 Target 객체의 JoinPoint를 호출하는 방식이라고 이해하면 된다.
JoinPoint는 Target이 가진 여러 메서드라고 볼 수 있다. Target에는 여러 메서드가 존재하기 때문에 어떤 메서드에 관심사를 결합할 것인지를 결정해야 하는데, 이 결정을 'Pointcut'이라고 한다.
Pointcut은 관심사와 비즈니스 로직이 결합되는 지점을 결정하는 것이다. 앞의 Proxy는 이 결합이 완성된 상태이므로 메서드를 호출하게 되면 자동으로 관심사가 결합된 상태로 동작하게 된다. 관심사(concern)는 위의 그림에서 Aspect와 Advice라는 용어로 표현되고 있다. Aspect는 조금 추상적인 개념을 의미하며, Aspect는 관심사 자체를 의미하는 추상명사라고 볼 수 있다. Advice는 Aspect를 구현한 코드이다.
위의 장황하게 설명해논 내용을 하나씩 다시 짚어보자면,
Join Point
: 모듈이 삽입되어 동작하게 되는 특정 위치 (메서드 호출 등)
애플리케이션을 실행할 때 특정 작업이 시작될 수 있는 시점을 의미한다. ‘클래스가 로드되는 시점‘ , ‘ 인스턴스가 생성되는 시점‘ , ‘메서드 호출 시점‘ 그리고 ‘예외가 발생하는 시점‘ 등이 조인포인트에 해당한다. 즉) 조인포인트는 어드바이스를 적용할 수 있는 시점들이다. 스프링에서는 프록시기반 AOP를 지원하기 대문에 메서드 호출 조인포인트만 지원한다.
Advice가 적용될 위치, 끼어들 수 있는 지점. 메서드 진입 지점, 생성자 호출 시점, 필드에서 값을 꺼내올 때 등 다양한 시점에 적용 가능
Point Cut
: 다양한 Join Point 중에 어떤 것을 사용할지 선택, 패키지이름/ 클래스이름/ 메서드이름을 정규식으로 지정한다. 조인포인트의 부분집합이며 실제 어드바이스가 적용되는 조인포인트를 의미한다. 스프링에서는 정규 표현식이나 AspectJ의 문법을 이용하여 포인트컷을 정의할 수 있다.
JointPoint의 상세한 스펙을 정의한 것. ‘A란 메서드의 진입 시점에 호출할 것'과 같이 더욱 구체적으로 Advice가 실행될 지점을 정의한다.
Advice
: Join Point에 삽입되어 있는 코드, aspect의 실제 구현체(클래스)를 의미한다. 핵심코드에 삽입되어 동작할 수 있는 공통코드와 시점을 의미한다. 즉) aspect를 언제 핵심 코드에 적용할 지를 정의한다. 어드바이스 시점은 before, after, after-throwing, after-returning, around가 있다. 실질적으로 어떤 일을 해야할 지에 대한 것, 실질적인 부가기능을 담은 구현체
Weaving
: Advice를 핵심 로직 코드에 적용하는 것 advice(공통코드)를 핵심 로직 코드에 삽입하는 것을 의미한다. 스프링은 런타임시 위빙을 지원한다.
1.컴파일시 위빙2.클래스 로딩 시 위빙3.런타임 시 위빙Aspect
: Ponint Cut + Advice 구현하고자 하는 보조기능을 의미, 어드바이저라고도 불린다. 여러 객체에 공통으로 적용되는 공통 관심 객체를 의미한다. 애스팩트 설정에 따라 AOP의 동작 방식이 결정 앞에서 설명한 흩어진 관심사를 모듈화 한 것. 주로 부가기능을 모듈화한다. (공통기능)
Target object
하나 또는 그 이상의 Aspect에 의해 Advice 되는 개체이다. 핵심 로직을 구현하는 클래스이다. Aspect를 적용하는 곳(클래스, 메서드,,,) 스프링 프레임워크에서 AOP 기능을 구현하는 방법 , 스프링 프레임워크에서 제공하는 API를 이용하는 방법, @Aspect 애너테이션을 이용하는 방법
Adivce는 실제 걱정거리를 분리해 놓은 코드를 의미한다. Advice는 그 동작 위치에 다라 다음과 같이 구분된다.
Advice는 과거의 스프링에서는 별도의 인터페이스로 구현되고, 이를 클래스로 구현하는 방식으로 제작했으나 스프링 3버전 이후에는 어노테이션만으로도 모든 설정이 가능하다. Target에서 어떤 Advice를 적용할 것인지 XML을 이용한 설정을 이용할 수 있고, 어노테이션을 이용하는 방식을 이용할 수 있다.
Pointcut은 Advice를 어떤 JointPoint에 결합할 것인지를 결정하는 설정이다. AOP에서 Target은 결과적으로 Pointcut에 의해 자신에게 없는 기능들을 가지게 된다. Pointcut은 다양한 형태로 선언해 사용할 수 있는데 주로 사용되는 설정은 다음과 같다.
반응형'Back-End > Spring Legacy' 카테고리의 다른 글
[Spring Framework] 정의와 특징 ( DI, IoC, AOP) (0) 2022.09.20 [5-ch18 Spring AOP] 설정, execution, args, @Around, @before, @AfterThrowing (0) 2022.09.07 [4-ch17 댓글 처리 ④] 댓글의 페이징 처리 (인덱스 생성, 화면 처리) (0) 2022.09.06 [4-ch17 댓글 처리 ③] jQuery와 Ajax 처리, JavaScript 모듈화 (0) 2022.09.01 [4 -ch17 댓글 처리 ② ] 서비스 영역과 Controller 처리 (@RequestBody, @PathVariable, consumes, produces ) (0) 2022.09.01