AOP
aspect-oriented programming
concern을 분리하여 모듈성을 증가시키는 것이 목적인 프로그래밍 패러다임이다.
wiki에 보면 "횡단 관심사(cross-cutting concern)의 분리를 허용"한다고 되어있다.
부가적인 기능(관심사)을 따로 모듈화하므로 OOP를 더욱 강화하는 방식이라고 볼 수 있다.
"흩어진 관심사를 Aspect로 모듈화한다"고 기억해두면 스프링 AOP를 이해하기 편하다!
∨ 프로그래밍 패러다임?
프로그래밍을 어떤 관점으로 바라보고 인식할 것이냐(=패러다임)를 말한다.
프로그래밍 패러다임은 크게 명령형/선언형으로 분류한다.
그중 OOP는 명령형 프로그래밍 패러다임에 속한다.
OOP를 더욱 OOP스럽게 만드는 것이 AOP이다.
+ 프로그래밍 패러다임?
명령형 프로그래밍 - "프로그램은 명령의 수행이다."
- 절차적 프로그래밍 (c언어)
- 객체지향 프로그래밍 (java)
선언형 프로그래밍 - "프로그래밍은 함수의 계산이다."
- 함수형 프로그래밍
>> 예시
명령형 | 선언형 |
How to에 초점 & 알고리즘을 명시 | What에 초점 & 목표를 명시 |
횡단보도까지 약 5m 이동하고, 초록불 일 때까지 기다렸다가 초록불이면 약 10m 앞으로 이동 | 초록불이 되면 길을 건넌다 |
∨ Cross Cutting Concern!
아래 그림과 같이,
Logging이나 Transaction처리, Security 부분은 여러 비즈니스로직에 공통으로 끼어들어가는 기능이다.
이를 모듈화하여 따로 두는 그 방식이 AOP(관점지향 프로그래밍)인 것이다!
다시말해서 "핵심기능에서 부가기능을 분리하여 따로 둔다"
AOP는 "흩어진 관심사를 Aspect로 모듈화하는 것"이라고 했다.
그러면 모듈화한 부가기능인 Aspect는 어떤 요소와 개념들을 가지고 있을까?
AOP 관련 요소와 개념
- Aspect : 따로 뺀 모듈!
- Target : 부가기능을 적용할 타겟
- Advice : 모듈에 대한 '구체적인 부가기능' (Aspect 클래스 내부에 메서드로서 존재함)
- JointPoint : '구체적인 부가기능'을 적용할 타겟(위치)를 지정하는 것
- PointCut : 더 상세히 '구체적인 부가기능'을 적용할 타겟(위치)를 지정하는 것 (JointPoint의 상세)
- Weaving : 타겟의 JointPoint에 Advice를 적용하는 과정!
용어를 이해하기 편하도록 풀어써보겠다.
""
Aspect는 모듈(따로 뺀 기능)이다.
그래서 Aspect라는 모듈은 여러 Advice(제공할 구체적인 부가기능)들을 담고 있다.
Advice(개별 부가기능)은 다른 핵심 로직들에 적용하는 거니까,
JointPoint(적용할 위치)를 지정해주어야 한다.
적용할 위치는 PointCut 설정을 통해 구체적으로 명시할수 있다.
""
용어는 낮설지만 쉽게 이해하면 뭐든 쉽다!
어려워하지 말고 자연스럽게 이해하자!
Aspect를 적용하는 시점은 크게 3분류된다.
특히 Spring의 AOP기능은 Runtime 시점에 동작한다!
Aspect 적용 시점
◆ (Source) 컴파일 시점
: AOP 전용 프레임워크가 존재한다.
공통 코드를 소스에 삽입하는 방법으로 적용할 수 있다.
◆ (Biinary) 클래스 로딩 시점
: 클래스를 로딩할 때 Aspect를 적용한다.
즉 바이트코드에 부가기능을 삽입하는 방식이다.
◆ (Runtime) 런타임 시점
: Spring에서 제공하는 AOP방식이다!
Proxy 방식으로 부가기능이 동작된다!
++ 이해 plus ++
Advice를 적용하는 과정인 Weaving의 시점은 위 3가지다!
참고) Spring AOP Proxy 관련 설명을 간단히 하고 지나가자
=> 궁금하면 따로 공부하기!
Spring의 AOP Proxy는 두가지 방식으로 구현되었다.
- JDK Proxy (Dynamic Proxy) : Target 객체가 인터페이스 기반일 때 적용
- CGLib Proxy : Target 객체가 클래스 기반일 때 적용
Spring AOP 사용해보기
먼저 dependency를 추가해야 한다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Spring AOP를 사용하는 방법 중 가장 일반적인 AspectJ를 이용하는 방법을 알아보자.
@AspectJ annotation을 사용하는 방식이다.
예제를 보는 것이 가장 이해가 빠를 것이다.
Aspect(모듈)을 클래스로 정의해뒀다.
이 Aspect에 담은 부가기능인 Advice가 존재한다.
각 부가기능인 Advice는 '지정될 타겟'을 명시해주게 된다. @Pointcut에 명시할 수 있다.
이제, 아래 LoggingAspect를 구경해보자.
@Aspect
@Component //Aspect는 Spring Bean으로 등록되어야 한다. 즉 Component로 등록해줘야 함!
// Logging 기능을 모듈화한 Aspect를 예제로 보자.
public class LoggingAspect {
private static final Logger log = LoggerFactory.getLogger(LoggingAspect.class);
// 부가기능이 적용될 위치인 PointCut을 따로 정의해두었다.
// @Pointcut(...) 괄호 안에 내용은 포인트컷만의 표현식을 통해 "지정할 대상"을 명시한 것이다.
@Pointcut("execution(public * org.prgrms.kdt..*.*(..))")
public void servicePublicMethodPointcut(){};
// 다음은 Advice이다. 즉 실제 부가기능을 구현한 것이다.
// 부가기능을 적용할 타겟이 호출될 때, 언제 Advice를 적용할 지 정해줘야 한다.
// └> @Before, @After, @Around, @AfterReturning, @AfterThrowing 등이 있다.
// 각각의 설명은 링크 참고
@Around("servicePublicMethodPointcut()") // Advice에 PointCut을 지정해줘야 한다.
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
// 구현한 Logging 부가기능!
log.info("Before method called. {}", joinPoint.getSignature().toString());
var result = joinPoint.proceed();
log.info("After method called with result => {}", result);
return result;
}
}
Advice 종류인 @Around, @Before ... 등을 더 알고싶으면
따로 검색해보거나 아래 링크를 참고하자.
https://hyuuny.tistory.com/100
'JAVA > Application' 카테고리의 다른 글
[JPA] Entity는 영속성 컨텍스트에 저장/조회한다! (4) | 2023.01.25 |
---|---|
Springboot Mybatis 사용해보기 ─ xml 파일로 쿼리문 관리 (0) | 2023.01.23 |
Spring MVC | Controller는 어떻게 요청을 처리하는 걸까? | Controller와 Servlet (0) | 2023.01.19 |
post 요청 후 406 Not Acceptable 해결 - Dto에 Getter 붙이기 (0) | 2023.01.16 |
JdbcTemplate | 왜 Jdbc 'Template'인가? 내부 동작 간단히 살펴보기 (0) | 2023.01.11 |