
Spring AOP(Aspect-Oriented Programming)를 활용하면 애플리케이션 전반에 걸친 공통적인 로직을 효율적으로 적용할 수 있습니다. 그중 하나가 로깅 기능입니다. Spring AOP 기반 로깅 설정의 원리를 살펴보겠습니다.
전체 코드
@Component
@Aspect
@Slf4j
public class LoggingAspect {
@Around("execution(* com.example..controller.*Controller.*(..)) " +
"or execution(* com.example..service.*Service.*(..)) " +
"or execution(* com.example..repository.*Repository.*(..))")
public Object logMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {
String componentType = "";
String className = joinPoint.getSignature().getDeclaringTypeName();
if (className.contains("Controller")) {
componentType = "Controller Layer : ";
} else if (className.contains("Service")) {
componentType = "Service Layer : ";
} else if (className.contains("Repository")) {
componentType = "Repository Layer : ";
}
return joinPoint.proceed();
}
}
1. @Component, @Aspect, @Slf4j
- @Component:
- Spring의 빈(Bean)으로 등록하여 **DI(Dependency Injection)**이 가능하도록 설정합니다.
- @Aspect:
- AOP 클래스임을 명시합니다. 이 어노테이션이 붙은 클래스는 공통 기능을 정의하는 역할을 합니다.
- @Slf4j:
- Lombok이 제공하는 로깅 어노테이션으로, log.debug(), log.info() 등의 메서드를 사용할 수 있도록 합니다.
2. 포인트컷(Pointcut)과 어드바이스(Advice)
2.1 포인트컷(Pointcut) 표현식
@Around("execution(* com.example..controller.*Controller.*(..)) " +
"or execution(* com.example..service.*Service.*(..)) " +
"or execution(* com.example..repository.*Repository.*(..))")
위 코드는 포인트컷 표현식을 정의하는 부분입니다.
- execution(* com.example..controller.*Controller.*(..))
- com.example 패키지 아래 controller 패키지에 있는 모든 Controller 클래스의 모든 메서드를 대상으로 설정합니다.
- execution(* com.example..service.*Service.*(..))
- com.example 패키지 아래 service 패키지에 있는 모든 Service 클래스의 모든 메서드를 대상으로 설정합니다.
- execution(* com.example..repository.*Repository.*(..))
- com.example 패키지 아래 repository 패키지에 있는 모든 Repository 클래스의 모든 메서드를 대상으로 설정합니다.
즉, Controller, Service, Repository 계층의 모든 메서드 실행 시 로깅이 수행됩니다.
2.2 @Around 어드바이스
public Object logMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {
- @Around 어노테이션은 메서드 실행 전후에 특정 로직을 삽입할 수 있도록 합니다.
- ProceedingJoinPoint 객체를 사용하면 대상 메서드의 실행을 제어할 수 있습니다.
3. 로그 출력
3.1 클래스 구분
String componentType = "";
String className = joinPoint.getSignature().getDeclaringTypeName();
if (className.contains("Controller")) {
componentType = "Controller Layer : ";
} else if (className.contains("Service")) {
componentType = "Service Layer : ";
} else if (className.contains("Repository")) {
componentType = "Repository Layer : ";
}
- 실행되는 클래스의 타입이 Controller, Service, Repository 중 어디에 속하는지 구분합니다.
3.2 로그 출력
log.debug(componentType + className + " ." + joinPoint.getSignature().getName() + "()");
- 최종적으로 클래스명과 실행된 메서드명을 로그로 출력합니다.
3.3 메서드 실행
return joinPoint.proceed();
- 대상 메서드를 실제로 실행하는 부분입니다.
- proceed()를 호출하지 않으면 대상 메서드가 실행되지 않습니다.
4. 실행 예시
4.1 Controller 메서드 실행 시 로그 예제
Controller Layer : com.example.app.controller.UserController.getUserInfo()
4.2 Service 메서드 실행 시 로그 예제
Service Layer : com.example.app.service.UserService.processUser()
4.3 Repository 메서드 실행 시 로그 예제
Repository Layer : com.example.app.repository.UserRepository.findById()

- Spring AOP를 활용하여 Controller, Service, Repository 계층의 모든 메서드 실행을 로깅하는 기능을 구현했습니다.
- @Around 어드바이스를 통해 메서드 실행 전후의 정보를 로깅할 수 있도록 설정했습니다.
- 비즈니스 로직을 수정하지 않고도 전역적으로 로깅을 적용할 수 있어 유지보수에 용이합니다.

'프로젝트 > 마이그레이션' 카테고리의 다른 글
Spring AOP를 활용한 트랜잭션 관리 설정 (0) | 2025.02.04 |
---|---|
스프링에서 전략 패턴(Strategy Pattern) 활용하기 (1) | 2025.02.03 |
Spring BeanNameGenerator 구현 (0) | 2025.01.24 |
Jackson 기반 JSON 유틸리티와 커스텀 ObjectMapper 적용하기 (0) | 2025.01.09 |