[Section2] Spring Framework 핵심 - AOP
🧑🏻💻 TIL(Today I Learned)
✔️ Spring Framework 핵심 개념 - AOP(Aspect Oriented Programming)
💡 AOP(Aspect Oriented Programming), 관심 지향 프로그래밍
➡️ 애플리케이션 개발의 과정에서 여러 객체에 공통적으로 적용할 수 있는 공통의 관심 사항(Cross-cutting Concern)과 핵심 로직과 관련한 핵심 관심 사항(Cross-cutting Concern)을 분리시키는 프로그래밍 기법
(애플리케이션의 보안, 로깅, 트랜잭션 등 공통적인 관심 사항을 따로 분리시켜 관리하는 것과 관련있음)
➡️ AOP를 사용하여 코드의 간결성과 재사용성을 높이고 객체지향 설계 원칙에 좀 더 부합하는 코드를 구현할 수 있음
🔎 프록시 객체
➡️ 스프링 프레임워크가 제공하는 AOP 방식은 런타임 시에 프록시(proxy) 객체를 생성해서 공통 관심 기능을 적용하는 방식

- 이렇게 실행 시간을 측정한다고 했을 때 ns(나노세컨드)에서 ms(밀리세컨드)로 바꿔야 한다면 * 표시 해준 부분들을 일일히 바꿔주어야 함
→ 즉 코드 중복이 일어난만큼의 수정이 필요함, 객체지향적이지 못함!
➡️ 이럴 때 사용할 수 있는 방법이 프록시 객체(Proxy Object), Proxy '대리' 즉 어떤 대상의 역할을 대리해서 처리하는 객체


- 이 클래스는 자체적으로 핵심 기능 로직을 가지고 있는 것이 아니라 생성자로 전달받은 객체에게 핵심 기능(calculate())의 실행을 다른 객체에게 위임하고 있음, 또한 실행시간을 측정하는 것과 같은 부가적인 기능에 대한 로직을 정의함
➡️ GugudanProxy 클래스와 같이 핵심 기능을 다른 객체에게 위임하고 동시에 실행 시간 측정과 같은 부가적인 기능을 제공하는 객체
"프록시(Proxy)"
프록시의 존재로 인해 코드의 중복을 없애고 기존 코드의 변경 없이도 실행 시간을 출력할 수 있음
➡️ 즉 GugudanProxy 클래스는 실행 시간 측정이라는 공통 사항 로직에 집중하고 GugudanByForLoop 클래스와 GugudanByRecursion 클래스에서 구구단 계산에 대한 핵심 기능을 담당하여 역할을 분리 시킴!
AOP 프로그래밍의 핵심
→ 핵심 기능을 구현한 코드의 수정 없이도 공통 기능을 적용할 수 있게 되었고 코드의 중복을 최소화시킬 수 있음
🔎 AOP의 핵심 개념
- AOP란 공통 관심 사항과 핵심 관심 사항을 분리시켜 코드의 중복을 제거하고 코드의 재사용성을 높이는 프로그래밍 방법론
- AOP는 핵심 기능에 공통기능을 삽입하는 것, 이를 통해 핵심 관심 사항 코드의 변경없이 공통 기능의 구현을 추가 또는 변경하는 것이 가능
✍🏻 AOP 구조

➡️ 위 그림과 같이 타켓 객체를 프록시 객체가 한번 감싸는 구조를 가짐
➡️ 설정에 따라 타깃 객체의 핵심 로직이 실행되기 전과 후에 공통 기능을 호출할 수 있음
➡️ 스프링의 경우 해당 프록시 객체를 스프링이 자동적으로 생성해주기 때문에 위 예시와 같은 GugudanProxy 클래스와 같은 객체를 만들 필요 없음
✍🏻 Aspect(애스팩트)
➡️ 공통 관심 사항에 대한 기능, AOP에서 A에 해당하는 부분
➡️ 공통 기능 적용 시점을 정의한 어드바이스(Advice)와 어드바이스가 적용될 지점을 정의하는 포인트컷(Pointcut)으로 구성
➡️ 트랜잭션이나 보안 등이 애스팩트의 대표적 예시

- 어드바이스(Advice)
: 공통 관심 사항과 적용 시점을 정의함, 무엇을 언제 적용할 지에 대한 것
타겟 객체에 종속되지 않기 때문에 순수하게 공통 기능에만 집중할 수 있음
📍 Advice의 종류 → 애너테이션 사용하여 다양한 시점에 원하는 기능 삽입 가능
- @Before : 타깃 객체의 메서드 호출 전에 공통 기능 실행
- @After : 예외 발생 여부에 관계없이 타깃 객체의 메서드 실행 후 공통 기능을 실행
- @AfterReturning : 타깃 객체의 메서드가 예외없이 실행되어 값을 반환한 경우 공통 기능을 실행
- @AfterThrowing : 타깃 객체의 메서드 실행 중 예외가 발생한 경우 공통 기능을 실행
- @Around : 타깃 객체의 메서드 실행 전과 후 또는 예외 발생 시 공통 기능을 실행, 가장 빈번하게 사용
- 조인 포인트(Joinpoint)
: 어드바이스가 적용될 수 있는 위치를 의미
메서드 호출, 필드 값 변경 등이 이에 해당하지만 스프링 AOP에서는 메서드 호출에 대한 조인 포인트만 제공 - 포인트컷(Pointcut)
: 조인 포인트의 부분 집합으로 공통 기능이 적용될 대상을 선정하는 방법
스프링 AOP의 조인 포인트는 메서드의 호출이므로, 스프링에서 포인트컷은 메서드를 선정하는 것과 관련
정규 표현식 또는 AspectJ 문법(execution 명시자 표현식)을 통해 정의 가능 - 위빙(weaving)
: 어드바이스를 핵심 기능 코드에 적용하는 것을 의미
시점에 따라 컴파일 시, 클래스 로딩 시, 런타임 시 위빙으로 구분가능하며 대부분의 경우 런타임 시 위빙 사용
스프링 AOP도 런타임 시 프록시 객체를 생성하여 공통 기능을 삽입하는 방법 사용함


- @Aspect -> 애너테이션을 사용하여 애스팩트 구현 가능
: 애스팩트는 공통 기능과 그 적용 시점을 정의한 어드바이스, 적용할 지점을 의미하는 포인트컷 포함 - @Pointcut -> 포인트컷을 구현하기 위한 애너테이션
: 애스팩트를 적용할 위치 선정, 포인트컷 설정을 보면 execution()으로 시작되는 명시자를 사용하여 어드바이스의 대상이 되는 메서드 지정하고 있음
: 주석에 있는 @Pointcut*("execution(* cal*(..))") 사용 가능

대괄호로 표시된 부분은 생략 가능하고, 각 패턴은 * 기호를 사용하여 모든 값을 표현하는 것이 가능함
점 두 개( .. ) 사용하여 0개 이상의 수를 표현할 수 있음
- @Around -> 타깃 객체의 메서드 실행 전과 후 또는 예외가 발생했을 때 사용
: 코드를 보면 @Around 애너테이션 값으로 targetMethod() 가 정의되어 있는데 이것은 targetMethod()에 정의한 포인트컷에 공통 기능을 적용한다는 것을 의미함
: 즉 정의한 대상 메서드들의 실행 전과 후에 공통 기능을 실행한다는 의미
: 위에서 공통 기능을 실행하는 메서드는 measureTime(), 메서드 바디에 실행 시간 측정을 위한 로직이 작성됨
📍ProceedingJoinPoint 인터페이스는 getSigniture(), getTarget() 등 호출한 메서드의 시그니처와 대상 객체를 구할 수 있는 메서드 제공
- ProceedingJoinPoint 인터페이스의 제공 메서드
메서드 | 설명 |
Signiture getSignature() | 호출되는 메서드에 대한 정보를 구한다. |
Object getTarget() | 대상 객체를 구한다. |
Object[] getArgs() | 파라미터의 목록을 구한다. |
- org.aspectj.lang.Signature 인터페이스는 호출되는 메서드와 관련된 정보를 제공하여 다음과 같은 메서드를 정의하고 있음
메서드 | 설명 |
String getName | 메서드의 이름을 구한다. |
String toLongString() | 메서드를 완전하게 표한한 문장을 구한다 (메서드의 리턴 타입, 파라미터 타입이 모두 표시됨) |
String toShortString() | 메서드를 축약해서 표현한 문장을 구한다. (기본 구현은 메서드의 이름만 구함) |
출처:https://ktko.tistory.com/entry/SpringProceedingJoinPoint%EC%9D%98%EB%A9%94%EC%84%9C%EB%93%9C
[스프링/Spring] ProceedingJoinPoint의 메서드
Spring ProceedingJoinPoint의 메서드 //Aspect 역할을 할 클래스를 선언하기 위해 어노테이션 선언 @Aspect public class ExeTimeAspect { //PointCut의 속성에 핵심코드의 어느 부분까지 공통 기능을 사용하겟다고 명
ktko.tistory.com
어렵다 AOP!!!!!!
'SEB_BE_45 > 공부 정리' 카테고리의 다른 글
[SEB BE] Section 2 회고 / 20230608 (0) | 2023.06.08 |
---|---|
[Section2] Spring Framework 핵심 - AOP2 (0) | 2023.06.07 |
[Section2] Spring Framework 2 (0) | 2023.05.31 |
[Section2] Spring Framework 1 (0) | 2023.05.31 |
[Section2] 데이터베이스 - 설계 (0) | 2023.05.26 |