본문 바로가기

카테고리 없음

AOP

728x90

1. AOP란?

 

 스프링에서 대표적인 개념 3가지가 있다. (IoC, AOP 그리고 PSA) 그중에서 AOP 에 대해서 말해보겠다. 코딩을 하다보면 서비스마다 비즈니스 로직들이 있을거고, 반면 공통되는 부가 기능이 있다.(로깅, 성능 측정, 데이터베이스 연결 등등) 여기서 우리가 핵심적으로 개발하고 싶은 부분은 당연히 비즈니스 로직이지만, 서비스마다 공통 되는 코드들이 퍼져있어 관리하는데 문제가 생긴다. 그림과 같이 A ,B ,C 서비스 가 있고 서비스마다 공통되는 X ,Y , Z 기능을 사용한다. 이상황에서 X -> X', Y -> Y', Z -> Z' 으로 바꾼다고 생각하면 일일히 다 바꿔줘야 될것이다. 그렇다고 X ,Y ,Z 를 함수로 묶은 후에 클래스에 넣는다고 하면 부가기능 함수와 기존 비즈니스 로직 클래스와 강한 의존관계를 가지게 된다.

 

 

  이렇게 서비스마다 흩어져있는 기능들을 Aspect 라는 것으로 모듈화 시킴으로써 비즈니스 로직으로부터 분리하여 재사용할수 있게 하는 것이 바로 AOP이다.

 

2. AOP 용어

 

- Target : AOP 가 적용될 타겟(클래스)

- Aspect : Target에 적용될 부가 공통 관심 사항(로깅, 보안, 트랜잭션 관리 등등) (Advice + PointCut)

- Advice : JoinPoint에 실행될 실제 코드

- JoinPoint : Advice가 적용될 위치

- PointCut : Advice를 적용할 JoinPoint을 선별하는 표현식

- Weaving : PointCut으로 결정된 타겟에 부가기능(Advice)를 삽입하는 과정)

 

Spring AOP 에서 사용되는 위 용어들에 대한 annotation 을 잘 정의해놨다. 자세한 annotation 은 docs.spring.io/spring-framework/docs/4.3.15.RELEASE/spring-framework-reference/html/aop.html

 를 참고하면 된다. 특히 Pointcut과 어드바이스 조합에 대한 어노테이션에 대해서 잘 알고 써야한다.

 

 

11. Aspect Oriented Programming with Spring

Aspect-Oriented Programming (AOP) complements Object-Oriented Programming (OOP) by providing another way of thinking about program structure. The key unit of modularity in OOP is the class, whereas in AOP the unit of modularity is the aspect. Aspects enabl

docs.spring.io

 

3. Weaving 의 종류

 

위빙은 Target 클래스에 미리 정의한 Advice를 적용하는 과정이다. 위빙 방법에는 크게 

1) 컴파일 타임 위빙, 2) 런타임 위빙, 3) 로드 타임 로딩이 있다.

 

3-1 컴파일 시점 위빙

 

AspectJ라는 특수한 컴파일러가 Aspect코드와 Base 코드를 입력받아 Weaving class 를 생성한다. 그림으로 보면 다음과 같다.

예제코드는 huongdanjava.com/compile-time-weaving-with-aspectj.html

여기를 참고 하면 좋을거 같다.

 

Compile-Time Weaving with AspectJ - Huong Dan Java

In this tutorial, I will introduce to you all detail about Compile-Time Weaving with AspectJ.

huongdanjava.com

 

 

3-2 런타임 위빙

 실제 런타임상에서 Method가 호출시 위빙이 이루어지는 것이다. (Source file, class 파일에도 변화가 없다.) 타겟 클래스의 프록시를 생성하여 비즈니스 코드와 Advice가 포함된 메소드를 호출하는 방식이다. 실제 Spring AOP 에서 이 방식을 사용하고 있다.

 

docs.spring.io/spring-framework/docs/3.2.0.RC1/reference/html/aop.html

의 9.3.7에 예제코드가 매우 잘 나와있다.

 

9. Aspect Oriented Programming with Spring

Aspect-Oriented Programming (AOP) complements Object-Oriented Programming (OOP) by providing another way of thinking about program structure. The key unit of modularity in OOP is the class, whereas in AOP the unit of modularity is the aspect. Aspects enabl

docs.spring.io

3-3 로드 타임 위빙

 

클래스가 JVM에 로드되는 시점에때 advice가 위빙이 되는 것을 말한다.

LoadTimeWeaver라는 위빙을 해주면 이는 spring-instrument 의존성에 포함되어있다.

해당 의존성을 추가해준 후 실행할때 jvm 옵션으로 전달하면된다.

그림으로 보면 다음과 같다.

아래 링크를 통해 스프링 환경에서 LTW를 사용하는 법을 참고하면 된다.

jehuipark.github.io/java/generic-object-di-try-with-spring

 

Load Time Weaving 적용기 - Spring LTW

스프링 환경에서 IOC 대상이 아닌 일반객체도 별도의 코드 작성없이 스프링 컨테이너로부터 DI 받을 수 있는 방법을 공유합니다.

jehuipark.github.io

 

3-4 위빙 성능 비교

 

- 실행시간은 CTW >>>>>>LTW >>> RTW 라고 한다. (컴파일 시간에 위빙이 되므로 어찌 보면 당연하다)

-  RTW 는 메소드에 대해서만 적용이 가능하지만, CTW, LTW는 클래스에 대해서도 적용이 가능하다.

- CTW 는 같은 코드를 조작하는 lombok과 같은 플러그인과 충돌이 날수도 있기 때문에 자신의 상황에 맞게 위빙 방식을 적용하면 될거 같다.

- 마지막으로 RTW 는 Spring 에서 사용하는 default AOP이기 때문에 쉽게 사용이 가능하지만, CTW나 LTW는 AspectJ와 같은 컴파일러나 라이브러리를 따로 설정해줘야 하며 JVM 옵션도 바꿔줘야한다.

 

 

4. 대표적인 Spring AOP 예제

 

@Transacational , @Async가 대표적인 Spring AOP 들이다.

Transactional의 기능을 생각해보면 다음과 같이 Advice 구조가 생겼을거라고 추측된다.

 

set autocommit = false

( 실제 쿼리가 포함된 비즈니스 로직)

쿼리 실패 예외발생시 -> rollback

쿼리를 모두 성공하면 -> commit

set autocommit = true

 

즉 대표적인 AOP 구조다.

 

 @Transactional 이 선언된 메소드나 클래스가 호출되면 기존 빈에 등록된 객체의 메소드가 호출되는 것이 아니라 위의 파란색 코드가 포함된 프록시 객체의 메소드가 호출될 것이다. 클래스 외부에서 프록시 객체를 만들기 때문에 반드시 메소드를  public으로 선언해줘야하며 inner method 가 transactional 일 경우에는 프록시를 우회하기 때문에(프록시 객체가 아닌 빈 객체를 호출 할 것이다.) 제대로 동작하지 않는다. 마찬가지로 final 메소드도 오버라이딩이 불가능하므로 AOP로 동작 안한다.

 

@Async도 비슷하다.

Async의 기능을 생각해봤을때 다음과 같은 Advice 구조가 생길것이라고 추측된다.

 

스레드를 만들거나 스레드 풀로부터 스레드를 받아옴

(실제 비즈니스 로직)

스레드에 run 함수에 비즈니스 로직 메소드를 붙인다.

스레드의 run 실행

 

@Transacational 과 마찬가지로 prviate 메소드와  inner 메소드에서는 동작 안한다.