상세 컨텐츠

본문 제목

Annotation(어노테이션)을 이용한 AOP

스프링부트

by e7e 2025. 12. 19. 18:38

본문

그 누구인가는 또 배운 걸 내게 묻는다.

문제는 안 쓰다 보니 나도 잊어 버렸당. 

더 커가는 문제는 모든 이유를 이젠 나이로 돌려버리는 습관이당.

 

안된당!.

다시금 의욕을 가지고 확인해 보장.

AOP (Aspect Of Point)  참 좋은 기능이당.

 

가장 흔하디 흔하고 초 간단하며 누구나 아하 하는 스토리로 하장.

성능 평가를 위해 특정 컨트롤러 메소드들의 실행 시간 측정을 

착하디 착한 스스로 열심인 고객이 요청을 했다고 하장.

 

실행 시간 측정이 필요한 메소드들에 @TimeCheck 어노테이션을 붙여서

해당 어노테이션이 붙은  메소드들에만 적용되는 Aspect를

만들어 log 출력을 하면 될꺼이당.

[ 일일이 메소드마다 필요한 코드를 붙이는 바보같은 행동을 막기 위해 AOP는 탄생했다]

 

 

pom.xml에  aop 추가하장

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
			<version>4.0.0-M2</version>
		</dependency>

 

 

먼저 어노테이션을 만들장. (method가 적용 타겟이당)

TimeCheck.java  (package는 com.e7e.annotaion)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeCheck {}

 

 

위 @TimeCheck 어노테이션이 붙은 메소드에 동작할 Aspect를 만들장.

TimeCheckAspect.java (package는 com.e7e.aspect)

@Slf4j
@Aspect
@Component
public class TimeCheckAspect {

	// 쭈의 어노테이션명은 동일한 패키지가 아니면 풀패키지 경로가 필요
	@Around("@annotation(com.e7e.annotation.TimeCheck)")
	public Object logTime(ProceedingJoinPoint joinPoint) throws Throwable {
		log.debug("항상 눈으로 확인 {}",joinPoint);
		long start = System.nanoTime();
		Object proceed = joinPoint.proceed();  // 실행 호출
		long runTime = System.nanoTime() - start;
		log.debug(joinPoint.getSignature().getName() + " 실행시간=> " + runTime + " ns");
		return proceed;
	}
}

 

이제 그저 테스트 해볼 초 심플 Controller를 맹글장.

AopTestController.java  (package는 com.e7e.controller)

@Slf4j
@RestController
@RequestMapping("/aop")
public class AopTestController {

	@TimeCheck    // 요게 붙었으닝, AOP 동작 join point
	@GetMapping("/test")
	public String testAop() {
		log.debug("요청이 왔어용");
		int sum = 0;
		for(int i=1; i<=99999;i++) {
		   	sum +=i;
		}
		log.debug("합 구했어용 {}",sum);
		return  "서버 콘솔 로그에서 실행시간 확인";
	}
}

 

서버를 실행 시키고, 브라우져에서 http://너의서버명:포트번호/aop/test 를 엔터를 꽝 치면 

분명 아래와 같은 내용이 보일 것이당.  그냥 그렇당.

항상 눈으로 확인 execution(String com.e7e.controller.AopTestController.testAop())
요청이 왔어용
합 구했어용 704982704
testAop 실행시간=> 1021200 ns

 

이런 벌써 끄시당.~~

앗! 잠깐!  TimeCheckAspect에서  Advice를 지정하기 위해 사용한

@Around 어노테이션에서 TimeCheck 어노테이션명을 패키지명 포함 고정문자열로

하는 것은 지금 시대는 별로 좋은 방법이 아니다.

아래 처럼 쓰면 변수처럼 동작하게 된당.  분명 더 좋을 꺼시당.

(메소드 매개변수에 TimeCheck timeCheck 가 있음에 주목하장)

 

TimeCheckAspect.java (수정본)

@Slf4j
@Aspect
@Component
public class TimeCheckAspect {

	@Around("@annotation(timeCheck)") // timeCheck가 변수로 동작
	public Object logTime(ProceedingJoinPoint joinPoint,TimeCheck timeCheck) throws Throwable {
		log.debug("항상 눈으로 확인 {}",joinPoint);
		log.debug("변수로 받아용 {}",timeCheck);
		long start = System.nanoTime();
		Object proceed = joinPoint.proceed();  // 실행 호출
		long runTime = System.nanoTime() - start;
		log.debug(joinPoint.getSignature().getName() + " 실행시간=> " + runTime + " ns");
		return proceed;
	}
}

 

결과는 같을 것이고, console 출력엔 아래 내용 더불어 나올거시당.

변수로 받아용 @com.e7e.rest.annotation.TimeCheck()

 

@PathVariable 식으로 받아들이면 Very Good이당.

기회가 있다면 두번째 방식으로 활용하여 좋은 점을 깊이 느끼장.

 


 그 얼만큼 그 얼마 전 그만큼 기념비적 결혼 기념일이었당.

 

불쑥 마님에 대한 미안함과 고마움이 심장에 교차로를 맹글었당.

 

애착 소파에 등딱지되어 넷플릭스와 유투브를 찐친으로

게으름의  세상에서 그 따위로

의미 있는 시간을 죽여가며  무의미 시간을 살아가는

나 자신이 나에게 보여서 더 그랬당.

 

둘러봐도 마음을 투명하게 담아 줄 게 없었당.

 

그 순간 이 노래가 들렸당.

음치라 직접 불러주지 못함이 또 가슴에 가시를 심는다.

 

https://www.youtube.com/watch?v=v-yI9x4IpZs

 

관련글 더보기