AOP : Aspect Oriented Programming
공통 관심 사항(cross-cutting concern) VS 핵심 관심 사항(core concern) 분리
한 가지의 상황을 예를 들어보자면..
이 전에 만든 회원 관리 프로젝트에서
모든 메서드의 호출 시간을 측정하고 싶다고 할 때..
또는 회원 가입 시간, 회원 조회 시간을 측정하고 싶다고 할 때..
스프링 컨테이너의 메서드에 전부 시간 측정 로직을 구현해 줘야 됩니다..
기존 MemberService 메서드
여기서 회원가입(join) 메서드와 회원 조회(findMembers) 메서드의 기능 시간을 측정하는 코드로 수정해 줍니다..
조회할 때 시간이 콘솔로 찍히는 걸 확인할 수 있습니다..
(오른쪽은 웹브라우저 짤린거입니다 ㅋㅁㅋ)
자 다시 돌아와서 여기서 문제는..
- 회원가입, 회원 조회에 시간을 측정하는 기능은 핵심 관심 사항이 아니다.
- 시간을 측정하는 로직은 공통 관심사항이다.
- 시간을 측정하는 로직과 핵심 비즈니스의 로직이 섞여서 유지 보수가 어렵다.
- 시간을 측정하는 로직을 별도의 공통 로직으로 만들기 매우 어렵다.
- 시간을 측정하는 로직을 변경할 때 모든 로직을 찾아가면서 변경해야 된다.
문제를 해결하기 위해 AOP를 적용해 볼게요..
우선 aop 패키지의 TimeTraceAop 클래스를 생성합니다..
package hello.hellospring.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class TimeTraceAop {
@Around("execution(* hello.hellospring..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
System.out.println("START : " + joinPoint.toString());
try {
return joinPoint.proceed();
} finally {
long end = System.currentTimeMillis();
long result = end - start;
System.out.println("END : " + joinPoint.toString() + " " + result + "ms");
}
}
}
AOP를 사용하기 위해 @Aspect 어노테이션을 사용하고
스프링 컨테이너에 객체를 올리기 위해 @Component 어노테이션을 사용했습니다..
@Around 어노테이션을 이용해 범위를 지정해 줍니다. 여기선 패키지 내 모든 메서드를 지정해 줬습니다..
ProceedingJoinPoint의 proceed 메서드를 사용함으로써 다음 메서드가 호출됩니다..
그리고 proceed 앞뒤로 이전에 작성했던 메서드 기능 시간을 측정하는 코드를 찍어줍니다..
마지막으로, 이제 메서드 호출과 관련해서 범위 내의 모든 메서드가 해당 기능을 통하게 되는데
이전에 Service 클래스에 작성해둔 코드는 제거해 줍니다..
컨트롤러 -> 서비스 -> 리포지토리
시작을 알리며, 끝날 때 시간을 출력하는 로직이 정상적으로 작동합니다..
문제에 대한 해결로..
- 회원가입, 회원 조회 등 핵심 관심사항과 시간을 측정하는 공통 관심사항을 분리한다.
- 시간을 측정하는 로직을 별도의 공통 로직으로 만들었다.
- 핵심 관심 사항을 깔끔하게 유지할 수 있다.
- 변경이 필요하면 이 로직만 변경하면 된다.
- 원하는 적용 대상을 선택할 수 있다.
AOP 적용 전 의존관계
컨트롤러 -> 서비스 -> 리포지토리
AOP 적용 후 의존관계
(프록시)컨트롤러 -> (실제)컨트롤러 -> (프록시)서비스 -> (실제)서비스 -> (프록시)리포지토리 -> (실제)리포지토리
순으로 적용됩니다..
'Java > Springboot' 카테고리의 다른 글
Spring Boot - Security 회원가입 (1) | 2025.03.08 |
---|---|
Spring Boot - Security 필터 체인 등록 (0) | 2025.03.08 |
Spring Boot - 스프링 데이터 JPA (0) | 2025.03.04 |
Spring Boot - JPA를 사용한 CRUD 게시판 만들기 (0) | 2025.03.04 |
Spring Boot - JPA (1) | 2025.03.03 |