
이 글은 스프링부트3 백엔드 개발자 되기 책을 바탕으로 공부한 내용을 정리한 게시글 입니다.
1. 관점 지향 프로그래밍(AOP)란?
스프링에서 또 하나 중요한 개념으로는 AOP(Aspect Oriented Programming)가 있습니다. 한국어로 관점 지향 프로그래밍으로 불리기도 하는데 의미를 풀어서 설명하자면 프로그래밍에 대한 관심을 핵심,관점,부가 관점으로 나누어서 관심 기준으로 모듈화 하는 것을 의미합니다.
예를 들어 계좌 이체, 고객관리하는 프로그램이 있을 때 각 프로그램에는 지금까지 벌어진 일을 기록하기 위한 로깅 로직과 여러 데이터를 관리하기 위한 데이터베이스 연결 로직이 포함됩니다. 이때 핵심 관점은 계좌 이체, 고객 관리 로직이고, 부과관점은 로깅, 데이터 베이스 연결 로직 입니다.

그림을 보면 핵심관점과 부가 관점으로 분리한것을 볼 수 있습니다.
부가기능은 핵심기능과 섞이면 설계와 코드가 지저분해지기 때문에 부가기능을 독립적인 모듈로 만들고자 하는 필요성이 대두되었습니다. 그래서 핵심 기능에 부여되는 부가기능을 효과적으로 모듈화 하는 방법을 찾다가 어드바이스와 포인트컷을 결합하여 발전시켜 AOP가 만들어지게 되었습니다.
- 포인트컷(PointCut): 메소드 선정 알고리즘을 담은 오브젝트
- 어드바이스(Advice): 타겟 오브젝트에 적용하는 부가 기능을 담은 오브젝트
부가 기능 모듈은 기존의 객체지향 설계와 구분 되는 새로운 특성이 있어서 Aspect라고 불리기 시작했습니다. Aspect는 애플리케이션의 핵심기능을 담고 있지 않지만 부가적인 관심사를 캡슐화한 모듈입니다.
Aspect가 적용 될 때 실행되는 구체적인 동작을 Adivce라 합니다.
Advice는 AOP의 핵심으로 어떤 로직이 실행 될 지 정의합니다.
이처럼 Aspect와 Adivice를 통해 어플리케이션의 핵심적인 기능에서 부가적인 기능을 분리하여 독특한 모듈로 만들고 설계하여 개발하는 방법을 AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)라고 부릅니다.
2. AOP는 주로 언제 사용될까?
AOP는 여러곳에서 반복적으로 필요한 작업(부가 기능)을 효과적으로 처리하고 싶을 때 사용합니다.
일반적으로는 아래와 같은 경우에 많이 활용됩니다.
- 로깅(Logging)
- 트랜잭션 관리
- 보안처리
- 예외 처리 및 알림
- 성능 모니터링 및 실행시간 측정
- 캐싱( Caching)
반복되는 작업을 효율적으로 관리하고 싶을 때나 핵심 비즈니스 로직과 부가 작업을 분리해 코드의 가독성을 높이고 유지보수를 쉽게 하고 싶을 때 AOP를 이용하게 됩니다.
AOP는 코드를 더 깔끔하게 유지하고 중복을 제거하기 위한 강력한 도구입니다.
3. Spring에서 AOP가 중요한 이유
Spring MVC 구조에서는 @Controller @Service, @Repository와 같이 관심사 별로 계층을 나눠 객체를 관리하게 됩니다.
AOP는 Spring이 관심사를 분리하는데 있어 아래와 같은 이유로 핵심적인 역할을 수행 할 수 있게 됩니다.
1. 핵심로직과 부가 로직의 분리
비즈니스 로직(핵심 관점)과 반복되는 부가 작업(부가 관점)을 분리함으로써 코드를 깔끔하게 유지 할 수 있습니다.
또한 핵심로직을 방해하지 않고 부가 로직을 쉽게 추가하거나 변경 할 수도 있습니다.
그럼 예시로 AOP를 이용하여 로깅(Logging)을 구현해 보겠습니다.
AOP 없이 로깅을 추가한 코드
public void processOrder(Order order) {
System.out.println("[LOG] 메서드 실행 시작");
try {
// 비즈니스 로직
orderService.save(order);
System.out.println("[LOG] 메서드 실행 성공");
} catch (Exception e) {
System.out.println("[LOG] 메서드 실행 중 예외 발생: " + e.getMessage());
}
}
AOP 적용 후
public void processOrder(Order order) {
// 핵심 비즈니스 로직만 남음
orderService.save(order);
}
@Aspect // AOP 클래스임을 명시
@Component
public class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("[LOG] 메서드 실행 시작: " + joinPoint.getSignature().getName());
Object result;
try {
result = joinPoint.proceed(); // 실제 비즈니스 로직 실행
System.out.println("[LOG] 메서드 실행 성공: " + joinPoint.getSignature().getName());
} catch (Exception ex) {
System.out.println("[LOG] 메서드 실행 중 예외 발생: " + ex.getMessage());
throw ex; // 예외를 다시 던져서 원래 로직에 영향을 미치지 않음
}
return result;
}
}
기존 코드와 비교해서 핵심관점인 비즈니스로직이 훨씬 깔끔해졌습니다. 기존 코드에서는 메서드마다 로깅로직을 추가해야 했습니다. 하지만 AOP를 사용하여 로깅로직을 한곳에서 관리하며, 여러 메서드에 공통적으로 적용 할 수 있게 되었습니다. 이렇게 AOP를 이용하여 핵심로직과 부가로직을 분리하여 부가로직을 모듈화 했을 때 3가지의 이점을 얻을 수 있습니다.
1. 반복 제거 및 재 사용성 증가
기존 코드에서는 메서드마다 로깅 로직을 추가해야 했습니다. 하지만 AOP를 사용하며 로깅 로직을 한 곳에서 관리하며 여러 메서드에 공통적으로 적용 할 수 있습니다.
- 기존 방식: 각 메서드에 로깅 코드 반복 작성 → 수정 시 모든 메서드 수정 필요.
- AOP 방식: 로깅 로직은 LoggingAspect 클래스에서 한 번 작성하면 끝.
2. 핵심 비즈니스 로직에 집중
기존 방식에서는 로깅 코드와 비즈니스 로직이 섞여 있어 핵심로직을 파악하기 어렵습니다. 하지만 AOP를 이용하면 비즈니스 로직만 남기고 부가로직(로깅)은 따라 분리합니다.
3. 로직 수정 확장 용이 및 유지보수성 향상
로깅 메세지를 변경하거나 새로운 로깅기능을 추가할 때 기존에 모든 메소드를 수정할 필요 없이 LoggingAspect클래스만 수정하면 됩니다. 또한 코드가 핵심로직과 부가 로직으로 분리되어 메서도가 많아져도 유지 보수가 훨씬 쉬워집니다.
2. 스프링의 주요 기능이 AOP에 의존
스프링에서 제공하는 많은 중요한 기능이 AOP를 기반으로 동작합니다. 예를 들어:
- 트랜잭션 관리 (@Transactional)
데이터베이스 트랜잭션은 AOP를 통해 메서드 실행 전후에 자동으로 관리됩니다. - 보안 (@PreAuthorize, @Secured)
메서드 호출 전에 권한 검사를 수행하는 로직이 AOP를 통해 구현됩니다. - 캐싱 (@Cacheable)
메서드 실행 결과를 캐시에 저장하거나 캐시를 조회하는 작업이 AOP로 처리됩니다.
AOP를 이용하면 Spring에서 코드의 가독성과 유지 보수성을 향상 시킬 수 있고 효율성과 재사용성을 높여 줍니다. 뿐만 아니라 스프링의 주요 기능이 AOP를 기반으로 동작합니다.
4. AOP 정리
AOP는 부가 관점을 모듈화하여 핵심 관심사(비즈니스 로직)와 부가 관심사를 분리하는 프로그래밍 기법입니다. AOP를 사용하면 다음과 같은 이점이 있습니다.
- 핵심 로직과 부가 로직 분리
- 로깅, 트랜잭션 관리 같은 부가 작업을 별도로 관리하여 핵심 로직을 깔끔하게 유지.
- 코드 중복 제거
- 공통 로직(로깅, 예외 처리 등)을 한 곳에서 정의하고 재사용 가능.
- 유지보수성 향상
- 부가 관심사를 수정할 때 각 메서드를 수정하지 않아도 되므로 수정 범위가 작아짐.
- 확장성
- 새로운 부가 관점을 쉽게 추가하거나 제거 가능.
- 가독성 개선
- 핵심 비즈니스 로직이 부가 관심사에 방해받지 않아 더 직관적.
이처럼 AOP를 이용하면 변경 및 확장이 쉬운 어플리케이션 설계를 가능하게 합니다.
'개발자 취업준비 > springboot' 카테고리의 다른 글
| 스프링부트 계층구조 (1) | 2025.01.28 |
|---|---|
| PSA(이식 가능한 서비스 추상화) (7) | 2025.01.21 |
| 제어의 역전(IoC)와 의존성 주입(DI) (1) | 2025.01.19 |
| 라이브러리와 프레임워크 (0) | 2025.01.15 |
| 서버와 클라이언트 (0) | 2025.01.13 |