일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Proxy
- 알고리즘
- springdatajpa
- AOP
- jpa
- Thymeleaf
- http
- JPQL
- Servlet
- SpringBoot
- 김영한
- Exception
- pointcut
- 인프런
- 그리디
- JDBC
- 자바
- db
- 스프링 핵심 기능
- transaction
- QueryDSL
- spring
- Android
- kotlin
- 백준
- Spring Boot
- java
- Greedy
- 스프링
- 스프링 핵심 원리
- Today
- Total
개발자되기 프로젝트
AOP 본문
- 모든 메소드의 호출 시간을 측정하고 싶다면?
- 공통 관심사항(cross-cutting concern) vs 핵심 관심사항(core concern)
각 메서드의 호출시간을 확인해 보자...
1. AOP 미사용 시
AOP를 사용하지 않으면, 일일히 하나하나 한땀한땀 코드를 넣어줘야 한다.
요렇게...
public Long join(Member member){
//같은 이름이 있는 중복 회원 x
long start = System.currentTimeMillis();
try{
validateDuplicateMember(member);
memberRepository.save(member);
return member.getId();
}finally { //로직이 끝날 때, 예외가 터졌을 때
long finish = System.currentTimeMillis();
long timeMs = finish - start;
log.info("join = {} ms", timeMs);
}
}
try & finally로 사용한 이유는 로직이 종료될 때 뿐 만 아니라, 예외가 터졌을 때도 메서드의 실행시간을 체크하기 위해!
이 행위를 모든 메서드마다 해야한다 ㅋㅋㅋㅋ
그런데.. 문제점 들이 발생한다.
- 시간 측정하는 기능은 핵심 관심 사항이 아님!
- 시간 측정 로직은 공통 관심 사항이다. 여기서기서 많이 쓰인다.
- 그런데 왜 서비스 로직과 시간측정 로직이 섞여 있어야 하냐?!
- 유지보수 어려워진다!
- 시간측정 로직 변경하려면 하나하나 찾아서 바꿔줘야 한다!
- 시간 측정만 별도로 공통 로직으로 만들기도 어렵다!
- ㅎ..human error나오기 딱좋음.
2. AOP란?
- AOP : Aspect Oriented Programming
- 공통 관심사항(cross-cutting concern) vs 핵심 관심사항(core concern) 을 분리!
3. AOP사용
* AOP생성
@Aspect
@Slf4j
//@Component
public class TimeTraceAop {
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable{
long start = System.currentTimeMillis();
log.info("START : {}", joinPoint.toString());
try{
Object result = joinPoint.proceed();// 다음 메서드로 진행
return result;
}finally {
long finish = System.currentTimeMillis();
long timeMs = finish - start;
log.info("END : {} {} ms", joinPoint.toString(), timeMs);
}
}
}
* Sping bean으로 등록
Service, Contorller 등 정형화된 것은 componnent 스캔을 활용하면 된다.
하지만 AOP는 special한 경우이기 때문에 SpringConfig를 통해 직접 @Bean으로 등록해주자.
Componnet 스캔 써도됨!
@Bean
public TimeTraceAop timeTraceAop(){
return new TimeTraceAop();
}
*@Around : 어디다가 적용할 거냐??
method에 @Around annotation을 적용하면 옵션에 따라 해당 AOP를 적용할 수 있다.
ex) 특정 class하위 등등
@Aspect
@Slf4j
//@Component
public class TimeTraceAop {
@Around("execution(* hello.hellospring..*(..))") //hellospring하뒤,, 여러옵션 있음.
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable{
long start = System.currentTimeMillis();
log.info("START : {}", joinPoint.toString());
try{
Object result = joinPoint.proceed();// 다음 메서드로 진행
return result;
}finally {
long finish = System.currentTimeMillis();
long timeMs = finish - start;
log.info("END : {} {} ms", joinPoint.toString(), timeMs);
}
}
}
--> 다만 이번에는 @Component 스캔을 사용하겠다.
왜냐하면 현재 @Around를 보면 TimeTraceAop는 hellospring package 하위 모든 메서드에 적용이 된다.
이 때 @Bean으로 등록하기 위해 든 SpringConfig 클래스도 hellospring 패키지 하위에 있다.
즉, TimeTraceAop를 Bean으로 등록하는 메서드도 TimeTraceAop에 적용이 되는 메서드가 되어 순환 참조가 일어난다.
@Around 를 통해 적용 범위를 변경하거나, @Component 스캔을 사용하면 된다.
* 즉 AOP는 중간에 intercepting에서 풀 수 있는 기술임
4. AOP작동 방법
- AOP 미적용
AOP 미적용 시에는 예를들어 Controller에서 Service를 호출하면 바로 호출이 되었다.
- AOP 적용
- 반면 AOP가 등록이 되고, Service에 적용이 된다고 해보자.
- Controller에서 Service를 호출하면 실제Service가 호출되는 것이 아니라,
- 스프링에서 빈으로 등록한 프록시 Service가 호출이 된다.
- 이후 Aop의 joinPoint.proceed()가 호출이 되면 실체 Service로 이동이 된다.
5. GitHub : 210724,AOP
'Spring Boot' 카테고리의 다른 글
Spring Data JPA (0) | 2021.07.24 |
---|---|
JdbcTemplate (0) | 2021.07.23 |
스프링 통합 테스트 (0) | 2021.07.23 |
Jdbc활용하여 Application에서 DB로 넘겨보자. (0) | 2021.07.23 |
H2 Database 설치 및 사용 법 (0) | 2021.07.23 |