AOP 에 대해서 자세하게 알아보겠습니다.
AOP란?
Aspect -Oriented Programming 관점 지향 프로그래밍 - 문제를 바라보는 관점을 기준으로 프로그래밍 하는 기법을 말한 다.
핵심 로직을 구현한 코드에 공통 기능 관련 코드가 포함되어 있지 않기 때문에 적용해야 할 공통 기능이 변경되더라도 핵심 로직을 구현한 코드를 변경할 필요가 없다. 단지 공통기능 코드를 변경 한 뒤 핵심 로직 구현 코드에 적용만 하면 된다.
분리를 허용함으로써 모듈성을 증가시키는 것이 목적인 프로그래밍입니다.
스프링의 IoC가 결합도와 관련된 기능이라면 AOP는 응집도와 관련된 기능이라고 할 수 있다.
AOP 용어
• Aspcet : 반복되어 사용되는 로직, 여러 객체에 공통으로 적용되는 공통 관심 사항
• target : Aspect 을 적용할 로직
• Advice : 반복 로직의 구현체 , 실질적으로 어떤 일을 해야 할지에 대한것, 실질적인 부가기능을 담은 구현체, 언제 공통 관심기능을 핵심 로직에 적용할 지를 정의
• jointpoint : Advice의 적용 위치 , 메서드의 실행시점
• PointCut: join Point의 상세한 스펙을 정의한것, advice 가 실행될 시점을 정합니다.
• Weaving : Advice를 핵심 로직 코드에 적용하는 것을 weaving이라고 한다. 즉 공통 코드를 핵심 로직 코드에 삽입하는 것이 weaving이다
AOP에서 각 관점을 기준으로 로직을 모듈화 한다는 것은 흩어진 관심사를 모듈화 하겠다는 의미
Weaving 방식
1.컴파일 시에 Weaving 하기
- AspectJ에서 사용하는 방식.
- 핵심 로직을 구현한 자바 소스 코드를 컴파일 할 때에 알맞은 위치에 공통 코드를 삽입. (AOP 가 적용된 클래스 파일이 생성.)
- 컴파일 방식을 제공하는 AOP 도구는 공통 코드를 알맞은 위치에 삽입할 수 있도록 도와주는 컴 파일러나 IDE를 함께 제공.
2. 클래스 로딩 시에 Weaving 하기
- AOP 라이브러리는 JVM이 클래스를 로딩 할 때 클래스 정보를 변경할 수 있는 에이전트를 제공.
- 에이전트는 로딩한 클래스의 바이너리 정보를 변경하여 알맞은 위치에 공통 코드를 삽입한 새 로운 클래스 바이너리 코드를 사용.
- 원본 클래스 파일은 변경하지 않고 클래스를 로딩 할 때에 JVM이 변경된 바이트 코드를 사용하 도록 함으로써 AOP를 적용.
- AspectJ 5 버전이 컴파일 방식과 더불어 클래스 로딩 방식을 함께 지원.
3. 런타임 시에 Weaving 하기
- 소스 코드나 클래스 정보 자체를 변경하지 않음.
- 프록시를 이용하여 AOP를 적용.
- 핵심 로직을 구현한 객체에 직접 접근하는 것이 아니라 중간에 프록시를 생성하여 프록시를 통 해서 핵심 로직을 구현한 객체에 접근
- 프록시 기반의 AOP 적용 과정(그림1 참조)
- 프록시는 핵심 로직을 실행하기 전 또는 후에 공통 기능을 적용하는 방식으로 AOP를 적용.
- 메서드가 호출될 때에만 Advice를 적용할 수 있기 때문에 필드 값 변경과 같은 Joinpoint에 대 해서는 적용할 수 없는 한계가 있음
스프링 AOP
- 프락시 기반의 AOP구현체입니다.
- 프록시 객체를 사용하는 것은 접근 제어 및 부가 기능을 추가하기 위해서
- 스프링 AOP는 스프링 Bean 에만 적용할 수 있습니다.
- 내부적으로는 프록시를 이용하여 AOP 가 구현되므로 메서드 호출에 대해서만 AOP를 적용할 수 있다.
프록시를 이용한 AOP 구현
▢ 스프링은 Aspect의 적용 대상이 되는 객체에 대한 프록시를 만들어 제공하고 있으며 대상 객체를 사용하는 코드는 대상 객체에 직접 접근하기 보다는 프록시를 통해서 간접적으로 접근하게 된다.
▢ 프록시를 통한 AOP (그림2 참조)
▢ 어떤 대상 객체에 대해 AOP를 적용할 지의 여부는 설정파일을 통해서 지정할 수 있으며 스프링은 설정 정보를 이용하여 런타임 시에 대상 객체에 대한 프록시 객체를 생성하게 된다.
▢ 대상 객체가 인터페이스를 구현하고 있다면 스프링은 자바 리플렉션 API가 제공하는 java.lang.reflect.Proxy를 이용하여 프록시 객체를 생성한다.
▢ 인터페이스를 기반으로 프록시 객체를 생성하기 때문에 인터페이스에 정의되어 있지 않은 메서드 에 대해서는 AOP가 적용되지 않는다.
▢ 인터페이스 기반 프록시 구조 (그림3 참조)
▢ 대상 객체가 인터페이스를 구현하고 있지 않다면 스프링은 CGLIB를 이용하여 클래스에 대한 프록 시 객체를 생성한다. CGLIB는 대상 클래스를 상속받아 프록시를 구현한다. 따라서 대상 프록시가 final인 경우는 프록시를 생성할 수 없으며 final 메서드에 대해서도 AOP를 적용할 수 없다.
참고 : https://code-lab1.tistory.com/193, https://yejun-the-developer.tistory.com/5
'Java&Spring' 카테고리의 다른 글
[ Java ] BufferedReader , BufferedWriter ,StringTokenizer (0) | 2023.08.06 |
---|---|
[Spring] spring? (0) | 2023.04.04 |
[Java&Spring] opp 정렬체 구현 (0) | 2023.03.27 |
댓글