일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 코드업
- 커스텀 데이터 학습
- Spring
- AWS
- 2021 제9회 문화공공데이터 활용경진대회
- @Transactional
- skt fellowship 3기
- yolo
- Expo
- google cloud
- STT
- JPA
- C++
- Spring Boot
- javascript
- 순환참조
- google login
- google 로그인
- YOLOv5
- pandas
- 양방향 매핑
- matplotlib
- idToken
- oauth
- 졸프
- marksense.ai
- html
- OG tag
- react native
- Loss Function
- Today
- Total
민팽로그
스프링 AOP 개념 간단 이해 본문
만약 내가 운영하는 서비스에서, 서비스를 가장 많이 이용한 Top5 고객에게 보상을 주는 이벤트를 진행하여 Top5 고객을 찾는 부가기능(핵심 기능의 수행시간 기록)을 추가해야 하는 상황이라면?
핵심기능 API별로 호출 시 수행 시간을 측정해 사용자의 총 수행시간을 저장하는 테이블을 관리한다고 하자.

위 그림과 같이 핵심기능마다 시간 측정을 위해 동일한 부가기능 코드가 추가되어야 할 것이다.
// 측정 시작 시간
long startTime = System.currentTimeMillis();
try {
// 핵심기능 수행
...
} finally {
// 측정 종료 시간
long endTime = System.currentTimeMillis();
// 수행시간 = 종료 시간 - 시작 시간
long runTime = endTime - startTime;
// 수행시간을 DB 에 기록
...
}
위 예제 코드와 같이 핵심기능마다 동일한 코드가 추가되어야 하는데, 핵심기능의 수가 매우 많다면 이를 모든 api마다 하나하나 추가하는것은 개발시간과 유지보수 측면에서 매우 비효율적이다.
AOP(Aspect Oriented Programming)를 통해 아래 그림과 같은 느낌으로 부가기능을 모듈화하여 사용할 수 있다.

- 어드바이스: 부가기능
- 포인트컷: 부가기능을 적용할 위치
스프링 AOP 개념적 이해

스프링 실제 동작

-> 스프링 서버가 기동될 때 프록시 객체가 중간에 삽입되어 프록시를 거쳐 핵심 기능을 DI를 하여 수행하게 됨
-> api 수행시간 기록을 예로 들면, 프록시에서 시작시간을 기록 후 핵심기능을 DI받아 핵심 기능을 수행한 다음, 다시 돌아와 종료시간을 기록
예제 코드: AOP를 사용해 모든 Controller에 부가기능 추가
@Component // 스프링 IoC 에 빈으로 등록
@Aspect
public class UserTimeAop {
private final UserTimeRepository userTimeRepository;
public UserTimeAop(UserTimeRepository userTimeRepository) {
this.userTimeRepository = userTimeRepository;
}
//해당 패키지 내의 모든 public 메소드에 대해 실행
@Around("execution(public * com.paeng.springcore.controller..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
// 측정 시작 시간
long startTime = System.currentTimeMillis();
try {
// 핵심기능 수행
Object output = joinPoint.proceed();
return output;
} finally {
// 측정 종료 시간
long endTime = System.currentTimeMillis();
// 수행시간 = 종료 시간 - 시작 시간
long runTime = endTime - startTime;
// 로그인 회원이 없는 경우, 수행시간 기록하지 않음
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.getPrincipal().getClass() == UserDetailsImpl.class) {
// 로그인 회원 -> loginUser 변수
UserDetailsImpl userDetails = (UserDetailsImpl) auth.getPrincipal();
User loginUser = userDetails.getUser();
// 수행시간 및 DB 에 기록
UserTime userTime = userTimeRepository.findByUser(loginUser);
if (userTime != null) {
// 로그인 회원의 기록이 있으면
long totalTime = userTime.getTotalTime();
totalTime = totalTime + runTime;
userTime.updateTotalTime(totalTime);
} else {
// 로그인 회원의 기록이 없으면
userTime = new UserTime(loginUser, runTime);
}
System.out.println("[User Time] User: " + userTime.getUser().getUsername() + ", Total Time: " + userTime.getTotalTime() + " ms");
userTimeRepository.save(userTime);
}
}
}
}
마치며
AOP와 proxy가 뭔지 대충 알 수 있었다. @Around 어노테이션에 대해 더 알아봐야겠다. 필요한 곳에 적용하려면 포인트컷 적용방법을 알아야할듯! 나중에 아래 링크로 간단히 공부해보기
참조
스파르타코딩클럽 [Spring 심화반]
Spring 뽀개고 취업하기
spartacodingclub.kr
'🍃spring boot' 카테고리의 다른 글
스프링 부트 시작: 인텔리제이&Gradle (0) | 2022.02.11 |
---|---|
spring 의존성 주입 3가지 방법 (0) | 2021.12.13 |
[OAuth] 웹에서 카카오 소셜 로그인 (0) | 2021.09.13 |
DI(Dependency Injection)와 스프링 IoC 컨테이너 (0) | 2021.09.12 |
servlet과 객체지향 프로그래밍(OOP:Object-Oriented Programming) (0) | 2021.09.12 |