본문 바로가기
Spring

스프링 AOP 개념

by 성건희 2018. 12. 24.
반응형

스프링 AOP

# AOP 란?

Aspect - Oriendted Programming

흩어진 Aspect를 하나로 모아서 모듈화 할 수 있는 프로그래밍 기법

 

AOP는 OOP와 서로 보완관계다.

= Aspect를 한곳으로 모음으로써 조금 더 OOP를 잘할 수 있도록 도와주는 역할

 

예를 들어보자.

학생 A, B, C가 있다.

학생들의 취미는 다음과 같다.

 

학생 A : 게임

학생 B : 노래부르기, 게임

학생 C: 랩 듣기, 노래부르기

 

위 처럼 비슷한 관심사들이 흩어져 있는 것을 '흩어진 관심사'. 즉, Crosscutting Concerns 라고 한다.

Concern : 여러 클래스, 혹은 여러 메서드에 걸쳐서 나타나는 비슷한 코드들을 의미

(ex) 트랜잭션 처리, 로깅 등..)

 

이런 Concern 중 하나에 변경사항이 발생하게 되면,

비슷한 Concern을 사용한 모든 코드를 다 뒤져가면서 코드를 손봐야 함.. 유지보수 문제 심각

 

위 문제를 AOP의 Aspect를 적용해서 해결할 수 있다.

 

# AOP를 적용하면?

Aspect 1 [게임] : 학생 A, 학생 B

Aspect 2 [노래부르기] : 학생 B, 학생 C

Aspect 3 [랩 듣기] : 학생 C

 

  1. Aspect로 흩어져있는 Concern들을 Concern별로 한 군데로 모음
  1. 실제 하던 일을 Aspect안에 독립적으로 정의
  1. 어디에 적용해야 하는지 정보를 입력

 

이처럼, 해야 할 일과 그 일을 어디어디에 적용해야 하는지 묶어서 모듈화함.

이것이 AOP다.

 

AOP의 용어를 완벽하게 이해할 필요는 없다.

감만 익히면 됨.

 

# AOP 주요 개념 정리

  • Aspect 는 묶은 것 (모듈)

  • 모듈 안에는 Advice 와 PointCut 이 있다.

  • Advice : 해야 할 일들 (게임, 노래부르기, 랩 듣기)

  • Target : 적용이 되는 대상 (학생 A, 학생 B, 학생 C)

  • Join point : 합류 지점, 스펙

    (메서드 호출할 때 끼어들기, 생성자 만들 때 끼어들기, 필드에서 값을 가져갈 때 끼어들기...)

  • Pointcut : 어디에 적용해야 하는지의 정보

    (ex) A라는 클래스안에 foo() 메서드를 호출할 때만 Advice를 적용하겠다.)

 

# AOP 구현체

  • 자바

    • AspectJ : 다양한 Join point와 엄청나게 많은 다양한 기능들을 제공
    • 스프링 AOP : 매우 국한적으로 기능을 제공

 

 

# AOP 적용 방법

  • 컴파일

    • 자바파일을 클래스파일로 만들 때, 바이트 코드를 조작하면서 조작이 된 바이트 코드를 생성

    • A라는 클래스에 foo() 메서드가 있고, Hello 라는 Aspect가 있다고 가정.

      Hello라는 Aspect는 A클래스의 foo() 메서드를 호출하기 전에 항상 Hello를 먼저 출력해야한다고 가정.

      그런 경우 컴파일이 되면 클래스 파일에 Hello를 찍는 메서드가 같이 들어있어야함.

  • 로드 타임

    • A라는 클래스에 foo()메서드가 있고, 순수한 클래스로 컴파일이 이루어짐

      그 후 A라는 클래스를 로딩하는 시점에 로딩하는 클래스 정보를 변경

      (로드타임 위빙 : 로드 타임에 뭔가를 끼워서 넣는 것)

      Aspect의 Hello를 찍는 메서드를 A라는 클래스를 로딩할 때 끼워서 넣음

      A라는 바이트코드는 그대로 있지만, 로딩하는 JVM 메모리 상에서는

      foo() 메소드 전에 Hello를 찍는 메서드가 같이 들어가 있는 상태로 로딩이 됨

    • 장점

      • AspectJ 사용으로 다양한 문법을 사용할 수 있다.
    • 단점

      • 로딩 시점에 약간의 성능부하
      • 로드타임위버설정을 해야함
  • 런타임

    • A라는 클래스(빈)에 Aspect 1 을 적용해야 한다는 것을 스프링이 이미 알고 있음.

      그래서 A라는 클래스 타입의 빈을 만들 때, A라는 타입의 프록시 빈 (A를 감싼)을 만든다.

      프록시 빈은 실제 A가 가지고 있는 foo() 메서드를 호출하기 직전에

      hello를 찍는 일을 먼저 하고, A를 호출한다.

      이 부분은 뒤에서 더 자세히 다루니 일단은 이렇게만 알고 넘어가자.

    • 주로 사용하는 방법

    • 최초의 빈을 만드는 초기의 성능이 약간 부하

    • 별도의 컴파일러나 로드타임위버 설정이 필요가 없다

    • 문법이 쉬움

    • 별도의 AOP용 공부를 많이할 필요가 없다

    • 가장 현실적이고 합리적인 선택

    • 경우에 따라서는 AspectJ가 제공하는 다양한 Join Point를 사용하는 경우가 있다.

      (이 경우 AspectJ 컴파일러로 컴파일을 하거나 별도의 자바 에이전트로 설정해서 로드타임위빙을 하는 방법으로 AspectJ와 연동해서 사용할 수 있다.)

 

# 참고

스프링 프레임워크 핵심 기술 - 백기선

 

반응형

댓글