장미정원
✨ 스프링 AOP 본문
AOP
AOP(Aspect Oriented Programming), 관점지향프로그래밍은 핵심기능과 부과기능을 구분하여 반복적으로 사용되는 기능을 모듈화하여 공통 관심사로 분리하여 프로그래밍하는 것입니다.
AOP를 구현하면 공통 기능이 추가되었을 대 핵심기능에 코드를 수정하지 않으면서 공통기능에 대한 구현을 추가하는 것입니다.
위와 같이 주문 관련 기능이 있다고 가정해보겠습니다. 여기서 각각의 핵심 기능인 주문받기, 주문정보조회 전, 후에 로그를 남겨야 한다면 각각의 핵심 기능 코드에 직접 로그를 출력하는 코드를 작성해야합니다. 이렇게 된다면 중복되는 코드가 많아지고 직접 핵심 기능의 코드를 수정해야하기 때문에 유지보수가 힘들어집니다.
여기서 AOP의 개념을 적용시킨다면, 핵심기능과 부과기능의 관점을 분리하여 공통되는 부과기능을 추출하여 공통된 부분을 추출하는것이 AOP의 개념입니다. 그리고 부과기능은 가로 방향의 공통된 부분을 추출했기 때문에 행단 관심사라고도 합니다.
AOP 용어
Aspect
- 공통 기능을들을 모듈화 한 것을 의미합니다. Advice와 PointCut을 가집니다.
Target
- Aspect(부과 기능)가 적용될 대상을 의미합니다. (ex. 메서드, 클래스)
JoinPoint
- Advice가 적용될 수 있는 위치를 의미합니다.
Advice
- Aspect의 기능을 구현한 것으로, Target에게 적용할 부과 기능들에 대한 코드를 의미합니다.
PointCut
- Advice를 적용할 JoinPoint의 범위를 지정하는 것을 의미합니다.
위의 예시 그림을 살펴보면 JoinPoint에는 주문받기기능, 주문정보조회기능이 있습니다. 이는 부과기능이 적용될 수 있는 지점을 의미합니다. AOP의 모듈이 Aspect 모듈 안에는 Advice(로그 출력), PointCut(주문 관련 기능들에 적용)이 존재합니다.
Spring AOP
스프링에서는 AOP의 개념을 쉽게 응용하여 사용할 수 있게 어노테이션을 제공해줍니다.
@Aspect
- 해당 클래스를 Aspect로 사용하겠다는 의미입니다.
@PointCut
- Advice를 적용시킬 범위를 지정할 수 있습니다.
@Around, @Before, @After 등등..
- Advice를 구현한 메서드임을 의미합니다.
스프링에서 AOP를 구현하는 방법
스프링에서는 AOP를 런타임 시점에 프록시 객체를 생성하여 공통 기능을 삽입하는 방식으로 AOP를 구현합니다. 그렇기 때문에 스프링에서 트랜잭션을 적용할때 사용하는 @Transactional 어노테이션을 사용할 때 private 메서드에는 적용할 수 없습니다. 프록시 객체는 런타임에 상속 클래스를 만들어서 오버라이딩하여 구현하기 때문입니다.
스프링에서 AOP 구현
아래는 간단하게 스프링에서 AOP 기능을 구현한 예제입니다.
LogAspect 클래스에 @Aspect 어노테이션을 붙혀 Aspect로 선언합니다. @Pointcout 어노테이션을 사용하여 메서드명이 order로 시작하는 모든 메서드에 Advice를 적용합니다. 아래 @Around 어노테이션이 붙은 메서드에서는 Advice를 구현합니다.
먼저 파라미터로 받은 JoinPoint로 실제 Target의 메서드명과 함께 시작 로그를 출력합니다. 그 후 JoinPoint의 proceed() 메서드를 실행시켜 실제 Target 메서드를 실행시킵니다. 그 후 로그를 출력 후 Target 메서드의 반환값을 return합니다.
이외에도 어노테이션을 기준으로 PointCut하는 방식도 있습니다. 위에서 잠깐 설명했던 스프링 트랜잭션 AOP와 같이 AOP개념을 잘 이용한다면 공통 로직에 대한 중복 코드를 줄일 수 있고 유지보수성을 향상시킬 수 있습니다.
'Back-end' 카테고리의 다른 글
✨ MSA와 클라우드 인프라 (0) | 2024.08.26 |
---|---|
[DB] 인덱스 진짜 이해하기 (1) | 2024.08.19 |
✨ GC 이해하기 (0) | 2024.08.02 |
✨ 스프링을 사용하는 이유 (0) | 2024.07.29 |
✨ JDBC와 DataSource (0) | 2024.07.01 |