DevBoi

[Spring] Aop란 본문

Develop/[Spring]

[Spring] Aop란

HiSmith 2022. 3. 26. 20:27
반응형

AOP : Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이라고 부른다.

AOP는 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어 보고 관점을 모듈화 하겠다는 것이다.

대표적으로 공통으로 처리하는 로직을 관점화한다.

ex.로깅,트랜잭션 등이 있다.

 

Advice : 실질적으로 어떤 일을 해야할지에 대한 것, 실질적인 부가기능을 담은 구현체(Aspect의 메소드 전체라고 이해하면 편하다.)

JointPoint : advice가 적용될 위치, 프로레스 완료, 생성자 생성, 필드에서 값을 꺼낼때 등등 사용가능(프로그램 실행중 특정지점) 

PointCut : JointPoint의 상세 스펙  (정규식이나 특정 패턴이 어떻게 일치해야 작동될지 정의)

 

스프링 AOP의 특징

- 프록시 패턴기반의 AOP 구현체, 프록시 객체를 쓰는 이유는 접근 제어 및 부가기능을 추가하기 위함

- 스프링 빈에만 AOP를 적용가능

- 모든 AOP 기능을 제공하는 것이 아닌 스프링 IOC와 연동

 

Spring Aop와 AspectJ는 다른 목표를 가진다.

-Spring Aop는 Spring Ioc에서 간단한 Aop구현을 제공하는것을 목표로 한다.

-Aspectj는 완전한 AOP 솔루션을 제공한다. AspectJ가 모든 도메인 객체에 적용될 수 있다

 

 

* AspectJ

-SpringAop 에서 지원하지 않는 필드에 대한 Advisor를 지원, Compile Time Weaving, Load TimeWeaving 같은

다양한 위방 방법을 제공한다.

 

RTW(Run Time Waving)

SpringAop에서 사용하는 방식, Proxy를 생성해 실제 타깃 오브젝트의 변형없이 위빙을 수행한다.

실제 런타임시 Method 호출 시에 위빙이 이루어지는 방식

-소스 파일,클래스 파일에 변형이 없지만, Point Cut에 대한 Advice가 늘어날수록 성능이 떨어진다.

 

CTW(Compile Time Weaving)

AspectJ에는 AJC 라는 컴파일러가 있다. Java Compiler를 확장한 형태의 컴파일러이다.

AJC를 통해 java파일을 컴파일 하며, 컴파일 과정에서 바이트 코드조작을 통해, Advisor 코드를 직접 삽입하여 위빙을 수행한다.

장점으로는 3가지 중, 가장 빠른 퍼포먼스를 보여준다.

lombok과 같이 컴파일 과정에서 코드를 조작하는 플러그인 과 충돌할 가능성이 높다.

 

LTW(Load Time Weaving)

ClassLoader를 이용해 클래스가 JVM에 로드될때 바이트코드 조작을 통해 위빙되는 방식

컴파일 시간은 CTW보다 짧지만, 오브젝트가 메모리에 올라가는 과정에서 위빙이 발생,

런타임시 CTW보다 느리다.

 

 

 

* Spring Aop의 동작과정

-Spring Aop는 타겟 객체에 대한 프록시를 만들어 제공한다.

-타겟을 감싸는 프록시는 Runtime에 생성된다.

-프록시는 어드바이스를 타겟 객체에 적용하면서 생성되는 객체이다.

-프록시가 호출을 가로챈다

 

-Spring Aop 는 Proxy를 기반으로 한 RuntimeWeaving 방식이다.

-Spring Aop에서는 JDK Dynamic Proxy와 CGlib를 통해 Proxy화 한다.

-JDK Dynamic Proxy는 reflection 기반, CGlib는 상속 기반으로 이루어진다.

 

<JDK dynamic Proxy>

JDK dynamic Proxy는 JDK에 내장되어있고, CGLIB는 오픈소스이다. 

만약 target Object가 적어도 하나이상의 Interface가 있다면,  JDK dynamic proxy가 사용되며,
interface를 구현한 메서드들이 proxy를 탄다.

인터페이스를 구현하지 않은 클래스라면, CGLIB의방식으로 AOP 프록시를 생성한다.

 

JDK dynamic proxy로 구현되면, interface가 존재하는 메서드만 proxy가 생성, interface를 강제화 하는 단점이있다.

Dynamic Proxy는 Invocation Handler를 상속받아서 실체를 구현하게 되는데 이 과정에서 특정 Object에 대해 Reflection을 사용하기 때문에 성능이 조금 떨어진다.

 

<CGLIB Proxy>

반대로 , CGLIB는 타깃에 대한 정보를 제공 받기 때문에 성능이 더 좋다. (상속방식을 사용해서 Overriding으로 지원)

CGLIB의 한계점은 

default 생성자 필요, 생성자 두번 호출 (Objensis 라이브러리의 도움을 받아 해결됨)

Spring은 JDK dynamic Proxy만 지원햇지만, Spring boot에서는 CGLIB의 3가지 한계를 보완해, interface던, 아니던

CGLIB를 제공한다.

 

Spring Aop는

순수 자바로 구현되어있고,

별도의 컴파일 과정이 필요없다.

런타임 위빙만 사용가능하고,

메소드 수준 위빙만 지원한다.

Spring 컴테이너가 관리하는 Bean에서만 구현이 가능하다.

 

 

<최종 정리>

Spring Aop는 프록시 패턴 기반의 AOP 구현체이다.

-Spring 은 타겟 객체에 대한 프록시를 만들어 제공한다.

-타겟을 감싸는 프록시는 실행시간에 생성된다.

-프록시는 어드바이스를 타겟 객체에 적용하면서 생성되는 객체이다.

-프록시가 호출을 가로챈다.

 

(동작과정)

호출자에서 타겟을 호출하게되면, 타겟이 아닌 타겟을 감싸고 있는 프록시가 호출되어, 

타겟 메소드 선,후 처리가 실행되도록 구성되어있다.

 

(생성 과정) - 자동으로 프록시를 생성하기 위해 DefaultAdvisorAutoProxyCreator 라는 클래스를 사용한다.

후 처리기는 빈으로 등록된 모든 어드바이저 내 포인트컷을 이용해, 전달 받은 빈이 프록시 적용대상인지를 확인한다.

프록시 적용대상이면 내장된 프록시 생성기를 통해, 현재 빈에 대한 프록시를 생성 + 어드바이저를 연결한다.

프록시가 생성되면 전달 받은 Target Bean 오브젝트 대신에 Proxy 오브젝트를 Spring Container에 돌려준다.

컨테이너는 빈 후처리가 돌려주는 프록시를 빈으로 등록한다.

이 후처리기를 통해, 빈으로 등록하지 않아도, 타겟 오브젝트에 대한 프록시 오브젝트를 빈으로 등록 할 수 있다.

 

반응형

'Develop > [Spring]' 카테고리의 다른 글

[Spring] Servlet이란?  (0) 2022.03.27
[Spring] Bean과 Component의 차이  (0) 2022.03.27
[Spring] DL? DI?  (0) 2022.03.25
[Spring] Spring Bean 등록 방법  (0) 2022.03.25
[Spring] 컨테이너  (0) 2022.03.25