AOP가 뭔가요?
- AOP를 설명하기 전, 한가지 상황을 예시로 들어보자.
/**
* 회원가입 메소드
*/
public Long join(Member member){
validateDuplicateMember(member);
memberRepository.save(member);
return member.getId();
}
- 위와 같은 회원가입, 회원 조회 등, 1000개의 메소드로 이루어진 회원 관리 프로그램이 있다.
- 모종의 이유로 회원관리 프로그램에서 모든 메소드의 호출시간과 종료시간을 측정해야 한다고 가정해보자
/**
* 회원가입 메소드
*/
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");
}
}
- 우리는 프로그램에 존재하는 모든 메소드에 위와 같이 시간을 측정하는 코드를 추가해야한다!
- 1000번의 반복끝에 어렵게 구현했지만.. 누군가가 "초단위로 구하도록 수정해줘!" 라고한다면? 아마 우리는 똑같은 작업을 1000번 더 해야할것이다.
- 이를 해결하기 위해 등장한 것이 바로 AOP 란 개념!
좀 더 자세히 설명해주세요!
- AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍 이라 부른다.
- 즉 어떤 로직을 공통 관심 사항 과 핵심 관심 사항 두가지 관점으로 나누어 각각 모듈화 하겠다는 의미
- 앞 선 예시에서는, 회원가입, 회원조회 등이 핵심 관심사항이 되고, 시간을 측정하는 것이 공통 관심 사항이 되는 것
- 공통 관심 사항과 핵심 관리 사항 두가지를 분리하여 로직을 짜게 되면, 앞선 예제처럼 공통 관심사항의 내용 변경이 필요할때, 모든 각각의 메소드들을 직접 수정을 하는것이 아닌 공통된 로직만을 수정하면 된다!
- 아래는 AOP를 활용하여, 공통 관심 사항인 시간 측정 로직을 따로 만들어 준 것이다.
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 //AOP는 이걸 적어줘야 쓸 수 있음
@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 finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("END: " + joinPoint.toString()+ " " + timeMs + "ms");
}
}
}
- aop라는 하위 패키지를 만들고 위와 같은 클래스를 만들어 줌으로써, 특정 패키지 하위에 있는 모든 메소드에 적용할 수 있는 시간 측정 기능을 만들 수 있다!
AOP는 어떻게 동작 되나요?
- 아래는 AOP 적용전의 스프링 컨테이너 동작이다.
- 스프링 컨테이너는 Controller와 service사이의 이런 의존관계가 있음을 알고 memberService를 호출하는 역할을 수행한다.
- AOP를 사용할 경우, AOP에 적용되는 서비스 실행 이전 스프링은 프록시(Proxy) 라 부르는 가짜 memberService를 만들어 세워 놓는다
- 이후 가짜 스프링빈이 끝나고 joinPoint.proceed()를 통해 진짜 memberService를 호출해주게 된다.
- 정리하자면, Controller가 호출하는 것은 프록시라는 기술로 인해 발생하는 memberService 인것이다
해당 게시글은 인프런 - 김영한 님의
[스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술] 강의에 기반합니다
'Programming > Spring' 카테고리의 다른 글
[Spring/스프링] 롤링페이퍼(게시판) 프로젝트 1. Entity 생성 (0) | 2022.03.22 |
---|---|
[Spring/스프링] 롤링페이퍼(게시판) 프로젝트 0. 프로젝트 설명 (0) | 2022.03.22 |
[Spring/스프링] Persistence Layer를 위한 JDBC, JPA (0) | 2022.03.06 |
[Spring/스프링] API (Application Programming Interface) (0) | 2022.02.26 |
[Spring/스프링] MVC와 템플릿엔진 (0) | 2022.02.26 |