Spring을 사용하다 보면 @Controller
, @Service
, @Transactional
같은 Annotation을 흔히 사용하게 됩니다.
하지만 이들 Annotation이 어떻게 동작하는지 궁금하지 않으셨나요?
이번 포스팅에서는 간단한 예제를 따라하며 Annotation의 원리를 이해하고, 실무에서 활용할 수 있는 커스텀 Annotation을 만들어보겠습니다.
Spring Annotation의 동작 원리
Spring Annotation은 자바의 메타 애노테이션(@Retention
, @Target
)과 리플렉션(Reflection)을 활용하여 동작합니다. 예를 들어, @Controller
는 내부적으로 @Component
를 포함하며 Spring Bean으로 등록됩니다.
1. 간단한 Annotation 원리 이해하기
다음은 간단한 커스텀 Annotation 예제입니다. 이 Annotation은 메서드 실행 전후로 로그를 출력합니다.
// Step 1: Annotation 정의
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExecution {
}
// Step 2: AOP 구현
@Aspect
@Component
public class LogExecutionAspect {
@Around("@annotation(com.example.annotation.LogExecution)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Method " + joinPoint.getSignature().getName() + " is starting...");
Object result = joinPoint.proceed();
System.out.println("Method " + joinPoint.getSignature().getName() + " has finished.");
return result;
}
}
2. Annotation 적용하기
이제 정의한 @LogExecution
Annotation을 메서드에 적용해봅시다.
// Step 3: 서비스 클래스에 적용
@Service
public class MyService {
@LogExecution
public void performTask() {
System.out.println("Performing a task...");
}
}
3. 실행 결과
MyService.performTask()
를 호출하면 다음과 같은 로그가 출력됩니다.
Method performTask is starting...
Performing a task...
Method performTask has finished.
실무 예제: API 요청 로그 기록
실무에서 자주 사용하는 예제로 API 요청 정보를 자동으로 기록하는 커스텀 Annotation을 만들어봅시다.
1. 커스텀 Annotation 정의
API 요청 로그를 기록하는 @LogRequest
를 만듭니다.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogRequest {
}
2. AOP로 로깅 로직 구현
@LogRequest
가 적용된 메서드의 요청 URL과 파라미터를 자동으로 기록합니다.
@Aspect
@Component
public class LogRequestAspect {
@Around("@annotation(com.example.annotation.LogRequest)")
public Object logRequest(ProceedingJoinPoint joinPoint) throws Throwable {
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
System.out.println("[Request] URL: " + request.getRequestURI());
System.out.println("[Request] Params: " + request.getParameterMap());
return joinPoint.proceed();
}
}
3. Annotation 적용
Controller 메서드에 @LogRequest
를 붙입니다.
@RestController
@RequestMapping("/api")
public class MyController {
@LogRequest
@GetMapping("/hello")
public String sayHello(@RequestParam String name) {
return "Hello, " + name + "!";
}
}
4. 실행 결과
/api/hello?name=Spring
요청 시, 다음과 같은 로그가 출력됩니다.
[Request] URL: /api/hello
[Request] Params: {name=[Spring]}
정리
Spring Annotation의 동작 원리를 이해하면, 커스텀 Annotation을 만들어 반복 작업을 자동화할 수 있습니다.
이번 글에서 만든 @LogExecution
과 @LogRequest
를 활용해 여러분의 프로젝트를 더 효율적으로 만들어보세요!
'스프링&스프링부트' 카테고리의 다른 글
[spring] AOP(관점 지향 프로그래밍) 이해하기: 실용적인 예제로 배우는 AOP (1) | 2024.01.21 |
---|---|
[Spring] yml 암호화를 해보자(feat. jasypt) (2) | 2024.01.03 |
[Spring] 메세지 컨버터란 (Spring message converter) (5) | 2023.11.01 |
[Spring] validation @NotNull @NotEmpty @NotBlank (0) | 2023.10.24 |