본문 바로가기
Java&Spring

[Spring] AOP 관점지향 프로그래밍

by JINJINC 2023. 4. 4.
728x90
반응형

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 적용과정
그림1.프록시 기반  aop 적용과정

  • 프록시는 핵심 로직을 실행하기 전 또는 후에 공통 기능을 적용하는 방식으로 AOP를 적용.
  • 메서드가 호출될 때에만 Advice를 적용할 수 있기 때문에 필드 값 변경과 같은 Joinpoint에 대 해서는 적용할 수 없는 한계가 있음

 

 

스프링  AOP

- 프락시 기반의   AOP구현체입니다.

- 프록시 객체를 사용하는 것은 접근 제어 및 부가 기능을 추가하기 위해서

- 스프링 AOP는 스프링  Bean 에만 적용할 수 있습니다. 

- 내부적으로는 프록시를 이용하여  AOP 가 구현되므로 메서드 호출에 대해서만  AOP를 적용할 수 있다. 

 

 

 

프록시를 이용한 AOP 구현

▢ 스프링은 Aspect의 적용 대상이 되는 객체에 대한 프록시를 만들어 제공하고 있으며 대상 객체를 사용하는 코드는 대상 객체에 직접 접근하기 보다는 프록시를 통해서 간접적으로 접근하게 된다.

프록시를 통한 AOP (그림2 참조)

그림2. 프록시를 통한  AOP 구조

▢ 어떤 대상 객체에 대해 AOP를 적용할 지의 여부는 설정파일을 통해서 지정할 수 있으며 스프링은 설정 정보를 이용하여 런타임 시에 대상 객체에 대한 프록시 객체를 생성하게 된다.

▢ 대상 객체가 인터페이스를 구현하고 있다면 스프링은 자바 리플렉션 API가 제공하는 java.lang.reflect.Proxy를 이용하여 프록시 객체를 생성한다.

▢ 인터페이스를 기반으로 프록시 객체를 생성하기 때문에 인터페이스에 정의되어 있지 않은 메서드 에 대해서는 AOP가 적용되지 않는다.

인터페이스 기반 프록시 구조 (그림3 참조)

그림3. 인터페이스 기반 프록시 구조

▢ 대상 객체가 인터페이스를 구현하고 있지 않다면 스프링은 CGLIB를 이용하여 클래스에 대한 프록 시 객체를 생성한다. CGLIB는 대상 클래스를 상속받아 프록시를 구현한다. 따라서 대상 프록시가 final인 경우는 프록시를 생성할 수 없으며 final 메서드에 대해서도 AOP를 적용할 수 없다.

 

 

 

 

 

 

 

 

 

 

 

 

 참고 : https://code-lab1.tistory.com/193, https://yejun-the-developer.tistory.com/5

728x90
반응형

'Java&Spring' 카테고리의 다른 글

[ Java ] BufferedReader , BufferedWriter ,StringTokenizer  (0) 2023.08.06
[Spring] spring?  (0) 2023.04.04
[Java&Spring] opp 정렬체 구현  (0) 2023.03.27

댓글