1. AOP(Aspect Oriented Programming)
1.1 AOP가 필요한 상황
- 상황
- 모든 메소드의 호출 시간 측정
- 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core cocern)
- 회원 가입 시간, 회원 조회 시간 측정 - 문제
- 시간을 측정하는 기능 → 공통 관심 사항 O, 핵심 관심사항 X
- 시간 측정 로직과 핵심 비즈니스 로직 섞여 유지보수 어려움
- 시간 측정 로직을 별도의 공통 로직으로 만들기 어려움
- 시간 측정 로직 변경 시, 모든 로직 찾아가 변경해야 함
# MemberService
@Transactional
public class MemberService {
/**
* 회원가입
*/
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");
}
}
/**
* 전체 회원 조회
*/
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");
}
}
1.2 AOP 적용
- 기능
- 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core cocern) 분리
- 시간 측정한즌 별도의 공통 로직 생성
- 변경 시, 시간 측정 로직만 변경하면 됨
- 원하는 적용 대상 선택 가능
⇒ 시간 측정 로직을 한 곳에 모은 후에 내가 원하는 곳에 적용시키는 것
@Aspect // AOP 사용 시 필요한 애노테이션
@Component // 스프링 빈 등록하기 위한 방법 1 -> 방법 2는 SpringConfig에서 직접 빈 들록
public class TimeTraceAop {
// 공통 관심 사항 타켓팅, 적용 대상 선택
// if)서비스 하위만 적용 => execution(* com.example.member.service..*(..))"
@Around("execution(* com.example.member..*(..))") // 패키지 하위에 다 적용
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable{
/* joinPoint => 호출 될 때마다 해당 지점에서의 action을 지정해줄 수 있음*/
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");
}
}
}
1.3 스프링 AOP 동작 방식
- AOP 적용 전 의존관계
- 아래 그림처럼 연결되어 의존관계로 호출
- AOP 적용 후 의존 관계(적용대상 : 패키지 하위 모두 적용)
- 스프링은 가짜(프록시: Proxy)를 생성
- 스프링 빈 등록 시, 가짜(프록시)를 앞에 세워놓고 연결
- 가짜 스프링빈 끝난 후, joinPoint.proceed()를 하여 실제 호출
- 컨트롤러가 호출하는 거는 프록시 기술로 발생하는 가짜 멤버서비스임
[ 출처 ]
'Spring > 개념' 카테고리의 다른 글
[스프링기본] CH02. 스프링 핵심 원리 이해1 - 예제 만들기 (0) | 2021.08.18 |
---|---|
[스프링기본] CH01. 객체지향설계와 스프링 (0) | 2021.08.16 |
[스프링입문] CH06. 스프링 DB 접근 기술 (0) | 2021.08.13 |
[스프링입문] CH05. 회원 관리 예제 - 웹MVC 개발 (0) | 2021.08.10 |
[스프링입문] CH04. 스프링 빈과 의존관계 (0) | 2021.08.10 |
댓글