Spring AOP(Aspect Oriented Programming )

문딤·2022년 10월 19일
0
post-thumbnail

AOP 란?

여러 객체에 공통으로 적용할수 있는 기능을 분리해서 재사용성을 높여주는 프로그래밍

❓ 이게 어떻게 재사용성을 높여줄까?

핵심 기능을 구현한 코드의 수정없이 공통기능을 적용할 수 있게 만든다.

+@ 프록시

모듈 단위 기능구현에서 핵심적인 기능의 실행은 위임하고, 부가적인 기능을 제공하는
객체를 프록시라 하겠다.

==> 데코레이터 패턴 객체에 가깝지만, 이해를 돕기위한 용어로 사용

+@ 데코레이터 패턴의 특징

데코레이터 패턴은 특정 개체의 기능을 정적으로 확장 (장식)하는 데 사용할 수 있으며, 디자인 타임에 일부 기초 작업이 수행되는 경우 동일한 클래스의 다른 인스턴스와 독립적으로 런타임에 일부 경우에 확장 할 수 있습니다. 이것은 원래 클래스를 래핑 하는 새로운 Decorator 클래스를 디자인함으로써 달성됩니다 .

위의 말의 뜻은 기초 작업이 수행되는 경우 독립적으로 다른 기능을 추가해서 원래 클래스를 wrapping(감싼다) 한다.

💨위의 말로 알 수 있는 데코레이터패턴의 장점은?

1) 기존 코드를 수정하지 않고도 데코레이터 패턴을 통해 행동을 확장시킬 수 있습니다.
2) 구성과 위임을 통해서 실행중에 새로운 행동을 추가할 수 있습니다.

=============================================================

핵심기능에 공통기능을 삽입하는 방법 3가지

  1. 컴파일 시점에 코드에 공통 기능을 삽입.

  2. 클래스 로딩 시점에 바이트 코드에 공통 기능을 삽입.

  3. 런타임시 프록시 객체를 생성해서 공통 기능을 삽입하는 방법.

    이 중 스프링에서는 3번째와 2번째 방식을 일부 지원한다.

    +@ 컴파일 시점, 클래스로딩 시점이란?

자바파일이 JAVAC 컴파일러를 거쳐 JVM이 해석할수있는 바이너리 클래스 코드로 변환되는 시점.

클래스 로딩시점 => 동적 로딩에 의해 JVM이 필요한 클래스를 런타임 데이터 영역(Runtime Data area) JVM의 메모리에 올리는 시점

프록시 기반 AOP

  1. 비지니스 로직 실행
    1-1 공통 기능 실행
    1-2 비지니스 핵심기능 실행
    1-3 RETURN
    1-4 공통기능 실행
    1-5 RETURN

AOP 주요 용어

용어의미
Advice어느시점에 공통 기능을 핵심 로직에 적용할지를 정의한다.
JoinPointAdvice를 적용 가능한 지점을 의미한다. (메소드 호출)
PointCutJoinpoint의 부분 집합, 실제 적용되는 포인트를 말한다.
WeavingAdvice를 핵심로직에 적용하는 것
Aspect여러 객체에 공통으로 적용되는 기능을 Aspect라한다.

ADVICE의 종류

용어의미
Before Advice대상 객체의 메소드 호출 전에 공통기능실행
After Returning Advice대상 객체의 메서드가 exception 없이 실행된 이후 실행
After Throwing Advice대상객체의 메서드가 exception이 발생한 경우 실행
After Adviceexception 발생 여부와 관계없이 메서드 실행후, 공통기능 실행
Around Advice위의 모든상황을 아우를때 사용.(모든상황에서 사용)

스프링 AOP 구현

  1. Aspect로 사용할 클래스에 @aspect 어노테이션을 붙인다.
  2. @PointCut 어노테이션으로 공통기능을 적용할 pointcut을 정의
  3. 공통기능을 구현한 메서드에 @Around 어노테이션을 적용한다.

프록시 객체의 우선순위

💨 @Order 어노테이션을 @aspect가 붙은 프록시클래스에 지정하면 우선순위가 정해진다.

Order값 숫자가 작을수록 우선 순위가 높아지고, 우선 적용되어서 더 안 쪽에서 감싸지는 proxy가 되어서 타겟 Object의 코드와 붙어있는 Apspect가 된다.

즉, Aspect 설정에서 order값의 숫자가 클 수록 target객체에서 더 멀어지는 바깥 쪽의 Proxy로 결합된다.


CacheAspect:Cache에 추가[7]
RecCalculator.factorial([7]) 실행 시간: 3143800 ns
CacheAspect: Cache에서 구함 [7]
RecCalculator.factorial([7]) 실행 시간: 91000 ns
CacheAspect:Cache에 추가[5]
RecCalculator.factorial([5]) 실행 시간: 85400 ns
CacheAspect: Cache에서 구함 [5]
RecCalculator.factorial([5]) 실행 시간: 140100 ns

==================================================>

RecCalculator.factorial([7]) 실행 시간: 23300 ns
CacheAspect:Cache에 추가[7]
CacheAspect: Cache에서 구함 [7]
RecCalculator.factorial([5]) 실행 시간: 5200 ns
CacheAspect:Cache에 추가[5]
CacheAspect: Cache에서 구함 [5]

한쪽이 다른 한쪽을 감싼것 같은데 누가 감싸진걸까? 안쪽에 있는 프록시객체가 감싸진 것으로 숫자가 더 낮을것이다.

우선순위가 높을수록 숫자가 낮아지므로, 부가기능인 Exetime 숫자가 높을것이다.

중요도가 더 높은 cache는 숫자가 낮다

profile
풀스택개발자가 될래요

0개의 댓글