코드스테이츠_국비교육/[Section2]

39.02_[Spring] AOP_22.10.18

생각없이 해도 생각보다 좋다. 2022. 10. 19. 00:04

>AOP

흩어진 관심사를 모아서 따로 처리하는 것이 AOP이다.

여기서 관심사는 Crosscutting Concerns을 의미한다. Crosscutting Concerns이란 객체(클래스)에서 핵심 로직이 아닌 부가적인 기능을 담당하는 부분을 말한다. 부가적인 기능을 담당하기 때문에 한 객체에만 있지 않고 해당 기능이 필요한 다른 객체에도 똑같이 존재할 수 있다.

즉, AOP란 객체들에 존재하는 Crosscutting Concerns들을 종류별로 모아서 처리하는 것이라고 할 수 있다.

>Aspect

같은 Crosscutting Concerns을 하나로 모아놓은 것을 Aspect라고 한다. 그리고 모아놓았다는 것은 모듈화를 했다는 의미와 같다.

>Target

Aspect를 적용할 객체(클래스)를 의미한다.

모든 Crosscutting Concerns을 Aspect로 만들었다면 다시 그 Aspect들을 원래 있던 장소에 적용시켜야 할 텐데, 여기서 적용시킬 원래 있던 장소를 Target이라고 한다.

>Advice

Aspect가 해야할 일(코드)에 대한 부분을 Advice라고 한다.

추가적으로 애너테이션의 사용으로 Advice의 순서나 실행 시점을 지정할 수 있다.

애너테이션으로는 @Order, @Before, @AfterReturning, @AfterThrowing, @After, @Around가 있는데, @Around가 가장 대표적이고 많이 쓰인다.

@Around를 중점으로 기억하자.

>Join Point

코드 흐름의 특정 부분을 의미한다. 좀 더 명확히는 AOP를 적용할 수 있는 모든 지점, 즉 Pointcut이 될 수 있는 부분들

을 의미한다.

예를 들면, 변수가 선언되는 코드도 하나의 Join Point이고, 메서드가 호출되는 코드도 하나의 Join Point이다. 이처럼 코

드 흐름에 지점이라고만 알고 있자.

>Pointcut

Aspect를 적용할 Target의 Join Point를 의미한다.

Target은 대충 이해는 가는데, Advice의 애너테이션도 실행 시점을 지정하고 Pointcut도 실행 시점을 지정하는거 아닌가? 같은건가?
라고 생각할 수 있다.

Target은 어떤 객체(클래스)에 Aspect를 적용할 것 인지이고, Pointcut은 해당 Target의 어떤 JoinPoint에서 Aspect를 적용할 것인지이다. Pointcut을 다르게 표현하면 Target의 내부 중 어디서 적용할 지에 관한 내용이다.
Advice의 애너테이션은 Aspect가 적용될 곳에서 세부적으로 어떤 시점에 적용할 것인지에 대한 내용이다. 다른 말로는 이미 적용할 JoinPoint가 있고, 그 JointPoint가 실행되기 전인지, 실행된 후인지와 같은 내용이다.

>AOP 구현체

AOP는 Java에만 국한된 개념이 아니다. 다양한 프로그래밍 언어를 사용하는 곳에도 적용되는 개념이다.

Java의 대표적인 AOP 구현체는 AspectJ와 Spring AOP가 있다.

  • AspectJ

다양한 기능과 다양한 Join Point를 제공하는 AOP 구현체이다.

  • Spring AOP

AspectJ보다 편하게 AOP를 사용하기 위해 만들어진 것이다. 매우 국한적으로 사용할 수 있지만, 편리하다.

>AOP 적용 방법

AOP를 적용하는 방법은 시점을 기준으로 3가지로 나뉘고, 각자의 장점, 단점, 그리고 가능한 부분이 다르다.

아래 시점1과 시점2는 AspectJ를 사용하고 시점3은 Spring AOP를 사용한다.

Spring AOP를 사용할 작업이 대부분이느 시점3을 위주로 기억해두길 바란다.

  • 1. 컴파일 시점

컴파일 시점, 즉 .java파일에서 .class가 되는 시점에 AOP를 적용하는 것을 의미한다.

자세히 설명하자면, 컴파일 시점에 AOP를 적용하는 것은 자바 소스 파일이 바이트 코드 파일로 되는 시점에 바이트코드들을 조작을 하여 최종적으로 만들어지는 .class 파일에 Apect를 끼워넣는 것이다.

  • 2. 로드 타임 시점

Target이 될 클래스를 로딩할 때, Aspect를 끼워 넣는 방식이다.

이를 Weaving이라고 하는데, 조금 더 자세히 설명하자면 Weaving은 Advice를 비즈니스 로직 코드(핵심 코드)에 삽입하는 것을 의미한다.

  • 3. 런타임 시점

시점1과 시점2의 경우는 모두 실행, 즉 런타임 이전에 해결하는 방식이다.

하지만 Spring AOP를 사용하면 런타임 도중에 AOP를 적용할 수 있다. 이게 가능한 이유는 Proxy 객체라는 개념때문이다.

Proxy객체는 쉽게 말하면 객체의 연결 통로 사이에 있는 징검다리이다.

애플리케이션이 작동할 때, 한 객체가 작동하기 위해서 다른 객체가 작동하는 것과 같이 유기적으로 작동할 것이다. 이는 객체간 의존 관계가 있기 때문이다.

이 의존 관계를 객체의 연결 통로라고 한다면, 그 사이에 Proxy라는 임시 객체를 만들어놓고 이 Proxy 객체에 Aspect를 끼워넣는 것이 런타임 도중에 AOP를 적용할 수 있는 이유이고 Spring AOP의 원리이다.

부연 설명으로 Spring의 의존 관계는 DI로 이뤄지므로, 이 Proxy 객체 또한 Bean으로 등록되어 사용될 것이다!