AOP(Aspect-Oriented Programming)는 객체지향 프로그래밍(OOP)을 보완하는 프로그래밍 패러다임으로,
횡단 관심사(Cross-cutting Concerns)를 모듈화하여 코드의 중복을 줄이고 유지보수성을 향상시키는 것을 목표로 합니다.
Spring Framework에서는 AOP를 핵심 기능 중 하나로 제공하고 있습니다.
1. AOP 주요 개념
- 애스펙트(Aspect): 횡단 관심사를 모듈화한 것으로, advice와 pointcut을 포함합니다.
- 어드바이스(Advice): 특정 조인 포인트에서 실행되는 코드입니다.
- 조인 포인트(Join Point): 어드바이스가 적용될 수 있는 위치입니다. (메서드 호출, 필드 접근 등)
- 포인트컷(Pointcut): 어드바이스를 적용할 조인 포인트를 선택하는 표현식입니다.
- 위빙(Weaving): 애스펙트를 대상 객체에 적용하여 새로운 프록시 객체를 생성하는 과정입니다.
2. AOP 구현 방식
Spring AOP는 프록시 기반으로 동작하며, 런타임 시에 프록시 객체를 생성하여 AOP를 구현합니다.
Spring AOP에서는 두 가지 방식의 프록시를 지원합니다.
- JDK 동적 프록시: 인터페이스 기반의 프록시를 생성합니다.
- CGLIB 프록시: 클래스 기반의 프록시를 생성합니다. (상속을 사용)
3. Spring AOP 구현
Spring에서는 어노테이션이나 XML 설정을 통해 AOP를 구현할 수 있습니다.
어노테이션 기반 AOP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@Aspect
@Component
public class LoggingAspect {
@Before(“execution(* com.example.service.*.*(..))”)
public void logBefore(JoinPoint joinPoint) {
// 메서드 실행 전 로깅
}
@AfterReturning(pointcut = “execution(* com.example.service.*.*(..))”, returning = “result”)
public void logAfterReturning(JoinPoint joinPoint, Object result) {
// 메서드 실행 후 로깅
}
@AfterThrowing(pointcut = “execution(* com.example.service.*.*(..))”, throwing = “exception”)
public void logAfterThrowing(JoinPoint joinPoint, Exception exception) {
// 예외 발생 시 로깅
}
}
|
cs |
XML 기반 AOP
1
2
3
4
5
6
7
8
9
|
<aop:config>
<aop:aspect id=“loggingAspect” ref=“loggingAspect”>
<aop:before pointcut=“execution(* com.example.service.*.*(..))” method=“logBefore”/>
<aop:after-returning pointcut=“execution(* com.example.service.*.*(..))” method=“logAfterReturning” returning=“result”/>
<aop:after-throwing pointcut=“execution(* com.example.service.*.*(..))” method=“logAfterThrowing” throwing=“exception”/>
</aop:aspect>
</aop:config>
<bean id=“loggingAspect” class=“com.example.aspect.LoggingAspect”/>
|
cs |
4. AOP 적용 예시
AOP는 다양한 횡단 관심사를 모듈화하는 데 사용될 수 있습니다. 대표적인 예시로는 로깅, 성능 모니터링, 트랜잭션 관리, 보안 등이 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
|
@Aspect
@Component
public class PerformanceMonitoringAspect {
@Around(“execution(* com.example.service.*.*(..))”)
public Object monitor(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long end = System.currentTimeMillis();
System.out.println(“Execution time: “ + (end – start) + “ms”);
return result;
}
}
|
cs |
AOP는 코드의 중복을 줄이고 모듈화를 촉진하여 애플리케이션의 유지보수성을 향상시키는 데 큰 도움을 줍니다. Spring AOP를 활용하면 간결하고 효과적으로 횡단 관심사를 처리할 수 있습니다. 하지만 AOP를 과도하게 사용하면 코드의 복잡성이 증가할 수 있으므로 적절한 수준에서 사용하는 것이 중요합니다.