2024. 6. 4. 17:21ㆍTIL
✔오늘 배운 중요한 🔑 point
- AOP 라는건 결국 중복된 부가기능의 작성을 없애고 싶어서 커스텀 어노테이션을 만들어서 적용시키는것
🎯 오늘 배운 내용
AOP : 핵심 로직 ,부가기능 분리해서 부가기능을 모듈화를 하여 재사용성을 매우 좋게 만드는 패러다임
옆에서 객체들을 바라보았을때 중복되는 부가기능들을 모듈화 하는것이 바로 AOP의 핵심이다
AOP 주요 개념!
- Aspect: 부가기능 모듈화한 단위
- PointCut: Aspect가 적용될 프로그램상 실제 위치
- JoinPoint: PointCutd의 후보군, Aspect가 적용될 수 있는 위치
- Advice: 실질적인 로직(함수)
- Weaving: Aspect를 실제 코드에 적용하는 과정
AOP를 적용할 수 있는 대표적인 2개의 프레임워크
Spring AOP:중간에 프록시를 통해서 객체에 접근하여 AOP 적용
AspectJ: JVM에서 클래스를 로딩할때 변경된 바이트 코드를 사용해 AOP 적용
SpringAop는 매우 사용하기 쉽지만 성능이 낮고
AspectJ는 성능이 뛰어나지만 사용하기 매우 어렵다
aop 사용방법!!(Spring AOP)
STEP 1 설정하기
dependencies {
implementation("org.springframework.boot:spring-boot-starter-aop")
}
build.gradle.kts에 해당 의존성을 추가한다
@EnableAspectJAutoProxy 어노테이션 작성
이제 proxy 기반으로 AOP를 사용할 수 있게 되었다
step 2 작성하기
커스텀 어노테이션 정의하기
package org.example.spartatodolist.infra.Aop
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class StopWatch()
infra 하위에 Aop라는 패키지를 생성한 뒤 annotation class를 만들어준다!
@Target은 어디에 적용이 될건지! -> 즉 AnnotationTarget.FUNCTION으로 설정해주면 함수 위에 붙이는 식으로 적용된다!
@StopWatch
override fun getCardById(cardId: Long): CardResponse {}
요런식으로 함수 위에 작성할수 있게 된다
@Retention은 이 어노테이션이 언제까지 유지될지를 설정한다. Kotlin에서는 AnnotationRetention.RUNTIME이 default값이다
커스텀 어노테이션 기능 작성하기
@Aspect
@Component
class StopWatchAspect {
private val logger= LoggerFactory.getLogger("Execution Time Logger")
@Around("@annotation(org.example.spartatodolist.infra.Aop.StopWatch)")
fun run(joinPoint: ProceedingJoinPoint) {
val stopWatch = StopWatch()
stopWatch.start()
joinPoint.proceed()
stopWatch.stop()
val methodName=joinPoint.signature.name
val methodArguments = joinPoint.args.joinToString(","){arg->arg?.toString() ?:"null"}
val timeElapsedMs= stopWatch.totalTimeMillis
logger.info("Method Name: $methodName | Arguments: ${methodArguments} | Execution Time: ${timeElapsedMs}ms")
}
}
@Aspect 어노테이션을 작성해서 해당 클래스가 Aspect임을 명시
@Component를 통해서 Bean으로 등록
private val logger= LoggerFactory.getLogger("Execution Time Logger")
로깅(시스템의 동작을 기록)을 위한 로거 설정
@Around("@annotation(org.example.spartatodolist.infra.Aop.StopWatch)")
fun run(joinPoint: ProceedingJoinPoint){}
@Around는 Advise의 적용시점 중 하나인데 실행 전후로 동작을 한다
"@annotation(org.example.spartatodolist.infra.Aop.StopWatch)" 는 해당 위치에 있는 annotation을 달았을때 run 함수를 작동시켜라! 라는 의미이다.
즉 @StopWatch 라는 어노테이션을 작성했을때 run 함수가 실행된다고 보면 된다
🤔 어떻게 활용할까?
해당 서비스의 함수가 실행되는 시간 뿐만 아니라 다양한 부가기능에 대해서 AOP를 활용하여 커스텀 어노테이션을 작성해서 코드의 재사용을 용이하게 할 수 있다.
하지만 Spring AOP를 사용했을 경우에 내부함수로 호출할경우에 작동이 되지 않는 등 여러 문제가 있는데 이러한 문제를 Trailing Lambda 문법을 사용해서 해결할 수도 있다.
📓 오늘의 한줄
For sale: baby shoes, never worn
- a six-word story -
'TIL' 카테고리의 다른 글
인가 (0) | 2024.06.06 |
---|---|
JWT토큰을 이용한 로그인 기능 (0) | 2024.06.05 |
팀 프로젝트 회고 (0) | 2024.06.03 |
적합한 유효성 검사? (0) | 2024.06.02 |
(알고리즘) 햄버거 만들기 (0) | 2024.06.01 |