AOP
AOP가 필요한 상황은 언제일까?
- 모든 메소드의 호출 시간을 측정하고 싶을 때
- 공통 관심 사항 vs 핵심 관심 사항
- 회원 가입 시간, 회원 조회 시간을 측정하고 싶을 때
MemberService에서 회원 조회 시간 측정을 추가 해주면
package hello.hello_spring.service;
import hello.hello_spring.domain.Member;
import hello.hello_spring.repository.MemberRepository;
import hello.hello_spring.repository.MemoryMemberRepository;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
/**
* 회원가입 */
public Long join(Member member) {
long start = System.currentTimeMillis();
try {
validateDuplicateMember(member); //중복 회원 검증 memberRepository.save(member);
return member.getId();
} finally {
long finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("join " + timeMs + "ms");
}
}
private void validateDuplicateMember(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
}); }
/**
* 전체 회원 조회 */
public List<Member> findMembers() {
long start = System.currentTimeMillis();
try {
return memberRepository.findAll();
} finally {
long finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("findMembers " + timeMs + "ms");
}
}
}
터미널에서 조회 시간이 이렇게 뜨는걸 확인할 수 있다. 처음 조회할 때는 원래 조금 오래 걸린다고 한다.
but
회원가입, 회원 조회에 시간을 측정하는 기능은 핵심 관심 사항이 아닌 공통 관심 사항이다! 저렇게 하면 시간을 측정하는 로직과 핵짐 비즈니스 로직이 섞여서 유지보수가 어려우며 별도의 공통 로직으로 만들기도 어렵고 변경할 때 모든 로직을 찾아가면서 변경해야 한다.
AOP 적용
AOP란? Aspect Oriented Programming
공통 관심 사항과 핵심 관심 사항을 분리할 수 있게 된다.
시간 측정 AOP를 등록해보자
package hello.hello_spring.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Component
@Aspect
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 finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("END: " + joinPoint.toString() + " " + timeMs + "ms");
}
}
}
start, hibernate, end가 뜨는걸 확인할 수 있다. (findMembers 57ms, join 22ms 등은 그냥 아까 멤버서비스에서 코드 추가해준 걸 안지워서 남아있는 것)
이걸 통해 어디서 병목이 일어나는지 확인할 수 있게 된다.
AOP를 통해 핵심 관심사항(회원가입, 회원 조회 등)과 공통 관심 사항(시간을 측정하는 것)을 분리해줬다. 변경이 필요하면 이 로직만 변경하면 되고 원하는 적용 대상도 선택할 수 있다.
AOP 동작 방식 이미지를 첨부하고 마무리!!
'WINK-(Web & App) > Spring Boot 스터디' 카테고리의 다른 글
[2025 1학기 스프링 부트 스터디] 이상래 #7주차 (0) | 2025.05.25 |
---|---|
[2025 1학기 스프링부트 스터디] 고윤정 #7주차 (0) | 2025.05.24 |
[2025 1학기 스프링 부트 스터디] 정다은 #7주차 (0) | 2025.05.24 |
[2025 1학기 스프링부트 스터디] 오세웅 #6주차 (0) | 2025.05.23 |
[2025 1학기 스프링부트 스터디] 최비성 #7주차 (0) | 2025.05.22 |